在php 5.4之前使用session_set_save_handler函数,进行用户自定义会话存储,这里不做详细介绍.
-
session_set_save_handler
设置用户自定义会话存储函数
这里仅只介绍关于PHP5.4版本中的两个系统内置类.
-
SessionHandlerInterface
Session设置的接口类
SessionHandlerInterface { /* 方法 */ abstract public bool close ( void ) abstract public bool destroy ( string $session_id ) abstract public bool gc ( int $maxlifetime ) abstract public bool open ( string $save_path , string $name ) abstract public string read ( string $session_id ) abstract public bool write ( string $session_id , string $session_data ) }
-
SessionHandler
SessionHandler implements SessionHandlerInterface { /* 方法 */ public bool close ( void ) public string create_sid ( void ) public bool destroy ( string $session_id ) public bool gc ( int $maxlifetime ) public bool open ( string $save_path , string $session_name ) public string read ( string $session_id ) public bool write ( string $session_id , string $session_data ) }
-
SessionHandler::open — Initialize session
在运行session_start()时执行
-
SessionHandler::close — Close the session
在脚本执行完成或调用session_write_close() 或 session_destroy()时被执行,即在所有session操作完后被执行
-
SessionHandler::read — Read session data
在运行session_start()时执行,因为在session_start时,会去read当前session数据
-
SessionHandler::write — Write session data
此方法在脚本结束和使用session_write_close()强制提交SESSION数据时执行
-
SessionHandler::create_sid — Return a new session ID
-
SessionHandler::destroy — Destroy a session
在运行session_destroy()时执行
-
SessionHandler::gc — Cleanup old sessions
执行概率由session.gc_probability 和 session.gc_divisor的值决定,时机是在open,read之后,session_start会相继执行open,read和gc
实际运用:
将SESSION保存在Redis中,并将Redis的结果进行加、解密
Session.php
class Session extends SessionHandler{ private $secureKey = null; private $redisClient = null; private $prefix = "session_"; public function __construct($secureKey){ $this->secureKey = $secureKey; $this->redisClient = new Redis(); $this->redisClient -> connect("10.77.144.224",10453); } public function write($id,$data){ $data = $this->encrypt($data, $this->secureKey); $key = md5($this->prefix.$id); return $this->redisClient -> set($key,$data); } public function read($id){ $key = md5($this->prefix.$id); $data = $this->redisClient -> get($key); return !$data ? "" : $this->decrypt($data, $this->secureKey); } public function destroy($id){ $key = md5($this->prefix.$id); return $this->redisClient->del($key); } /* * 对称解密函数 */ public function decrypt($data,$password){ $data = base64_decode($data); $salt = substr($data, 0, 16); $ct = substr($data, 16); $rounds = 3; // depends on key length $data00 = $password.$salt; $hash = array(); $hash[0] = hash('sha256', $data00, true); $result = $hash[0]; for ($i = 1; $i < $rounds; $i++) { $hash[$i] = hash('sha256', $hash[$i - 1].$data00, true); $result .= $hash[$i]; } $key = substr($result, 0, 32); $iv = substr($result, 32,16); return openssl_decrypt($ct, 'AES-256-CBC', $key, true, $iv); } /* * 对称加密函数 */ public function encrypt($data,$password){ $salt = openssl_random_pseudo_bytes(16); $salted = ''; $dx = ''; // Salt the key(32) and iv(16) = 48 while (strlen($salted) < 48) { $dx = hash('sha256', $dx.$password.$salt, true); $salted .= $dx; } $key = substr($salted, 0, 32); $iv = substr($salted, 32,16); $encrypted_data = openssl_encrypt($data, 'AES-256-CBC', $key, true, $iv); return base64_encode($salt . $encrypted_data); } } ini_set('session.save_handler', 'user'); $key = 'secret_string'; $handler = new Session($key); session_set_save_handler($handler, true); session_start();
write.php
require_once("Session.php"); $_SESSION["aa"] = "aaa"; $_SESSION["bb"] = "bbb"; $_SESSION["cc"] = "ccc";
get.php
require_once("Session.php"); print_R($_SESSION);exit;
输出结果:
Array ( [aa] => aaa [bb] => bbb [cc] => ccc )
Pingback引用通告: 彻底理解PHP的SESSION机制 | 精彩每一天