一個基於redis的處理session的方法,如下。
1 <?php 2 class Session_custom { 3 private $redis; // redis實例 4 private $prefix = 'sess_'; // session_id前綴 5 6 // 會話開始時,會執行該方法,連接redis服務器 7 public function open($path, $name) { 8 $this->redis = new Redis(); 9 return $this->redis->connect("127.0.0.1",6379); 10 } 11 12 // 會話結束時,調用該方法,關閉redis連接 13 public function close() { 14 $this->redis->close(); 15 return true; 16 } 17 18 // 會話保存數據時調用該方法,在腳本執行完或session_write_close方法調用之後調用 19 public function write($session_id, $data) { 20 return $this->redis->hMSet($this->prefix.$session_id, array('expires' => time(), 'data' => $data)); 21 } 22 23 // 在自動開始會話或者通過調用 session_start() 函數手動開始會話之後,PHP 內部調用 read 回調函數來獲取會話數據。 24 public function read($session_id) { 25 if($this->redis->exists($this->prefix.$session_id)) { 26 return $this->redis->hGet($this->prefix.$session_id, 'data'); 27 } 28 return ''; 29 } 30 31 // 清除會話中的數據,當調用session_destroy()函數,或者調用 session_regenerate_id()函數並且設置 destroy 參數為 TRUE 時,會調用此回調函數。 32 public function destroy($session_id) { 33 if($this->redis->exists($this->prefix.$session_id)) { 34 return $this->redis->del($this->prefix.$session_id) > 0 ? true : false; 35 } 36 return true; 37 } 38 39 // 垃圾回收函數,調用周期由 session.gc_probability 和 session.gc_divisor 參數控制 40 public function gc($maxlifetime) { 41 $allKeys = $this->redis->keys("{$this->prefix}*"); 42 foreach($allKeys as $key) { 43 if($this->redis->exists($key) && $this->redis->hGet($key, 'expires') + $maxlifetime < time()) { 44 $this->redis->del($key); 45 } 46 } 47 return true; 48 } 49 } 50 51 // 調用自定義的session處理方法 52 $handler = new Session_custom(); 53 session_set_save_handler( 54 array($handler, 'open'), 55 array($handler, 'close'), 56 array($handler, 'read'), 57 array($handler, 'write'), 58 array($handler, 'destroy'), 59 array($handler, 'gc') 60 ); 61 62 // 下面這行代碼可以防止使用對象作為會話保存管理器時可能引發的非預期行為,表示當腳本執行之後或調用exit()之後,存儲當前會話數據並關閉當前會話 63 register_shutdown_function('session_write_close'); 64 65 session_start(); 66 67 // 可以使用session了
補充:
php.ini文件中的session.gc_probability與session.gc_divisor兩個配置選項共同決定gc函數調用的時機。默認值分為為1和1000,表示每個請求只有1/1000的機會調用gc函數。