通過redis實現session共享

Lance發表於2020-09-10
<?php
class redisSession{
    /**
     * 儲存session的資料庫表的資訊
     */
    private $_options = array(
        'handler' => null, //資料庫連線控制程式碼
        'host' => null,
        'port' => null,
        'lifeTime' => null,
        'prefix'   => 'PHPREDIS_SESSION:'
    );

    /**
     * 建構函式
     * @param $options 設定資訊陣列
     */
    public function __construct($options=array()){
        if(!class_exists("redis", false)){
            die("必須安裝redis擴充套件");
        }
        if(!isset($options['lifeTime']) || $options['lifeTime'] <= 0){
            $options['lifeTime'] = ini_get('session.gc_maxlifetime');
        }
        $this->_options = array_merge($this->_options, $options);
    }

    /**
     * 開始使用該驅動的session
     */
    public function begin(){
        if($this->_options['host'] === null ||
           $this->_options['port'] === null ||
           $this->_options['lifeTime'] === null
        ){
            return false;
        }
        //設定session處理函式
        session_set_save_handler(
            array($this, 'open'),
            array($this, 'close'),
            array($this, 'read'),
            array($this, 'write'),
            array($this, 'destory'),
            array($this, 'gc')
        );
    }
    /**
     * 自動開始回話或者session_start()開始回話後第一個呼叫的函式
     * 類似於建構函式的作用
     * @param $savePath 預設的儲存路徑
     * @param $sessionName 預設的引數名,PHPSESSID
     */
    public function open($savePath, $sessionName){
        if(is_resource($this->_options['handler'])) return true;
        //連線redis
        $redisHandle = new Redis();
        $redisHandle->connect($this->_options['host'], $this->_options['port']);
        if(!$redisHandle){
            return false;
        }

        $this->_options['handler'] = $redisHandle;
//        $this->gc(null);
        return true;

    }

    /**
     * 類似於解構函式,在write之後呼叫或者session_write_close()函式之後呼叫
     */
    public function close(){
        return $this->_options['handler']->close();
    }

    /**
     * 讀取session資訊
     * @param $sessionId 通過該Id唯一確定對應的session資料
     * @return session資訊/空串
     */
    public function read($sessionId){
        $sessionId = $this->_options['prefix'].$sessionId; 
        return $this->_options['handler']->get($sessionId);
    }

    /**
     * 寫入或者修改session資料
     * @param $sessionId 要寫入資料的session對應的id
     * @param $sessionData 要寫入的資料,已經序列化過了
     */
    public function write($sessionId, $sessionData){
        $sessionId = $this->_options['prefix'].$sessionId; 
        return $this->_options['handler']->setex($sessionId, $this->_options['lifeTime'], $sessionData);
    }

    /**
     * 主動銷燬session會話
     * @param $sessionId 要銷燬的會話的唯一id
     */
    public function destory($sessionId){
        $sessionId = $this->_options['prefix'].$sessionId; 
        return $this->_options['handler']->delete($sessionId) >= 1 ? true : false;
    }

    /**
     * 清理會話中的過期資料
     * @param 有效期
     */
    public function gc($lifeTime){
        //獲取所有sessionid,讓過期的釋放掉
        //$this->_options['handler']->keys("*");
        return true;
    }

}

呼叫

$handler = new redisSession(array( 'host' => "127.0.0.1",'port' => "6379" )); 
$handler->begin();
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章