在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机制 | 精彩每一天