PHP对 Session 进行自定义处理

在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 )

PHP对 Session 进行自定义处理》上有1条评论

  1. Pingback引用通告: 彻底理解PHP的SESSION机制 | 精彩每一天

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>