1. 程式人生 > 其它 >Redis專題(十)——Redis儲存Session

Redis專題(十)——Redis儲存Session

Redis專題(十) ——Redis儲存session

(原創內容,轉載請註明來源,謝謝)

一、概述

PHP預設是將session存於伺服器的檔案中。當併發量大,此方式效率低,因此可以採用redis儲存session。

要改變session的儲存位置,首先要改變php.ini中的配置項session.save_handler,將其值設定為user。

二、改變儲存位置函式

php內建的函式session_set_save_handler可以重新設定session的儲存方式,包括session的開啟、關閉、寫入、讀取等。

session_set_save_handler方法實質上不僅實現儲存位置由檔案變為redis(或其他使用者定義的儲存型別如memcache),還需要自定義session被開啟、關閉、設定、讀取、銷燬、回收等情況下,php具體去執行的內容。因此,該方法傳入的變數全是回掉函式。

該方法的具體內容,在php官方文件中,定義如下:

boolsession_set_save_handler ( callable $open , callable $close , callable $read ,callable $write , callable $destroy , callable $gc [, callable $create_sid [,callable $validate_sid [, callable $update_timestamp ]]] )

具體定義如下:

1、open

當session被開啟時,會自動呼叫此函式。類似於類的建構函式。

2、close

當session關閉時呼叫的函式,類似於解構函式。

3、read

如果會話中有資料,read 回撥函式必須返回將會話資料編碼(序列化)後的字串。 如果會話中沒有資料,read回撥函式返回空字串。

其中,儲存在session的內容如果是陣列、物件,必須序列化後儲存,而session呼叫此函式後會自動將值進行反序列化。

4、write

當要儲存session資料時,當前會話 ID 以及 $_SESSION 中資料序列化之後的字串作為引數。序列化後的資料將和會話 ID 關聯在一起進行儲存。當呼叫 read 回撥函式獲取資料時,所返回的資料必須要和傳入 write 回撥函式的資料完全保持一致。

5、destroy

呼叫session_destroy時會呼叫此函式。

6、gc

會話回收清理舊資料時呼叫的內容。

7、create_id

當需要重新生成新的會話id時呼叫的函式。

三、PHP實現session儲存於redis

         <?php
//類的功能——實現將session儲存在redis
class SessionSaveRedis{
         private $redis;
         private $sessionPath;
         private $sessionName;
         private$sessionExpireTime = 100;
         //建構函式,連線redis
         public function__construct(){
                   $this->redis= new Redis();
                   $this->redis->connect('127.0.0.1',6379);
                   $this->loadSession();
                   session_start();
         }
         //載入自定義session方法
         public functionloadSession(){
                   session_set_save_handler(
                            array($this,'open'),
                            array($this,'close'),
                            array($this,'read'),
                            array($this,'write'),
                            array($this,'destroy'),
                            array($this,'gc')
                   );
         }
         public functionopen($path, $name){
                   return true;
         }
         public functionclose(){
                   return true;
         }
         //存入redis時,key採用session:id,
//便於統一管理所有的session,與redis中儲存的其他內容作為區分
         public functionread($id){
                   $value =$this->redis->get('session:' . $id);
                   if($value){
                            return$value;
                   }else{
                            return'';
                   }
         }
         public functionwrite($id, $data){
                   if($this->redis->set('session:'. $id, $data)){
                            $this->redis->expire('session:'. $id, $this->sessionExpireTime);
                            returntrue;
                   }
                   returnfalse;
         }
         public functiongc($time){
                   return true;
         }
         public function__destruct(){
                   session_write_close();
         }
}

——written by linhxx 2017.08.14