一、建立會話表
在數據庫上建立簡單的sessions表,php
CREATE TABLE sessions( id CHAR(32) NOT NULL, data TEXT, last_accessed TIMESTAMP NOT NULL, PRIMARY KEY(id) );
二、定義會話函數,讓PHP來使用這些函數
經過調用session_set_save_handler()函數來完成。調用它須要6個參數,每一個參數都是一個函數名,見表:mysql
次序 | 函數被調用的時機 |
1 | 啓動會話 |
2 | 關閉會話 |
3 | 讀取會話數據 |
4 | 寫入會話數據 |
5 | 銷燬會話數據 |
6 | 舊的會話數據應該被刪除(執行垃圾收集程序) |
如今先根據須要創建這6個函數:sql
/* *打開會話的函數 */ public function open_session(){ global $sdbc; $sdbc = mysqli_connect('localhost','root','','test',3306); if($sdbc == false) return false; return true; } /* *關閉會話函數 */ public function close_session(){ global $sdbc; return mysqli_close($sdbc); } /* *讀取會話數據的函數 */ public function read_session($sid){ global $sdbc; //query the database $sql = sprintf('SELECT sid FROM mb_sessions WHERE sid = "%s"',mysqli_real_escape_string($sdbc,$sid)); $result = mysqli_query($sdbc,$sql); if(mysqli_num_rows($result) == 1){ list($data) = mysqli_fetch_array($result,MYSQL_NUM); return $data; }else{ return ''; } } /* *向數據庫寫入數據的函數 *$sid 會話ID *$data 會話數據,是數組$_SESSION序列化的結果 */ public function write_session($sid,$data){ global $sdbc; $sql = sprintf('REPLACE INTO mb_sessions (sid,data) VALUES ("%s","%s")',mysqli_real_escape_string($sdbc,$sid), mysqli_real_escape_string($sdbc,$data)); $result = mysqli_query($sdbc,$sql); if(mysqli_num_rows($result) >0) return true; else return false; } /* *銷燬會話數據的函數 */ public function destory_session($sid){ global $sdbc; $sql = sprintf('DELETE FROM mb_sessions WHERE sid = "%s"',mysqli_real_escape_string($sdbc,$sid)); if(mysqli_num_rows(mysqli_query($sdbc,$sql)) > 0) return true; else return false; } /* *垃圾回收函數 */ public function clean_session($expire){ global $sdbc; $q = sprintf('DELETE FROM mb_sessions WHERE DATE_ADD(last_accessed,INTERVAL %d SECOND) < NOW()',(int)$expire); $r = mysqli_query($sdbc,$q); return true; }
使用會話處理函數:數據庫
session_set_save_handler('open_session','close_session','read_session','write_session','destroy_session','clean_session');
再啓動會話,注意這二者的順序不能調換!數組
session_start();
文件保存爲db_session.inc.php。瀏覽器
這裏,須要注意如下幾點:session
- session_set_save_handler並不會啓動會話,咱們還須要調用session_start()來啓動。若是session_start()在以前執行,腳本中定義的處理函數就會被忽略而得不到執行。
- 每次到新的頁面能夠先經過調用require_once(' db_session.inc.php '),從而簡化步驟
- 若是在PHP設置裏session.auto_start = 1(意味着每一個頁面將會自動啓動會話),就不能使用函數session_set_save_handler()。
- 在腳本運行結束以後,數據庫鏈接是自動關閉的,而後會話函數會嘗試向數據庫寫入數據並關閉鏈接,這樣就會致使產生一系列莫名其妙的問題。爲了不這些問題,咱們應該在腳本執行結束以前調用session_write_close()函數,他會調用「寫入」和「關閉」函數,而這時數據庫鏈接仍是存在的。
- 在使用header()函數重定向瀏覽器以前也應該調用session_write_close()函數。