2008年9月12日 星期五

PHP Session 改存放到 MySQL 中

目前使用環境
Fedora 7
Php 5
MySQL

問題起源
當它們全都安裝在同一台 Server ,一直都很順利。但是一旦將 MySQL 抽離到別台 Server 安裝後,怪異的事情就發生了,網頁偶爾會莫明的卡住,停止不動...........
經由一些測試後,發生是卡在 Session.start() .......所以猜測是 session 的檔案被 lock 或啥之類,網路上沒找到啥特別解法,所以最後就嘗試將 Session 改寫到 MySQL 之中。
也就開始了以下的實作內容。

PHP SESSION 的工作原理
在 解決問題之前,先來瞭解一下 PHP SESSION 的工作原理。在用戶端(如流覽器)登錄網站時,被訪問的 PHP 頁面可以使用 session_start() 打開 SESSION,這樣就會產生用戶端的唯一標識 SESSION ID(此 ID 可通過函數 session_id() 獲取/設置)。SESSION ID 可以通過兩種方式保留在用戶端,使得請求不同的頁面時,PHP 程式可以獲知用戶端的 SESSION ID;一種是將 SESSION ID 自動加入到 GET 的 URL 中,或者 POST 的表單中,預設情況下,變數名為 PHPSESSID;另一種是通過 COOKIE,將 SESSION ID 保存在 COOKIE 中,預設情況下,這個 COOKIE 的名字為 PHPSESSID。這裡我們主要以 COOKIE 方式進行說明,因為應用比較廣泛。
那麼 SESSION 的資料保存在哪裡呢?當然是在伺服器端,但不是保存在記憶體中,而是保存在檔或資料庫中。預設情況下,php.ini 中設置的 SESSION 保存方式是 files(session.save_handler = files),即使用讀寫檔的方式保存 SESSION 資料,而 SESSION 檔保存的目錄由 session.save_path 指定,檔案名以 sess_ 為首碼,後跟 SESSION ID,如:sess_c72665af28a8b14c0fe11afe3b59b51b。檔中的資料即是序列化之後的 SESSION 資料了。如果訪問量大,可能產生的 SESSION 檔會比較多,這時可以設置分級目錄進行 SESSION 檔的保存,效率會提高很多,設置方法為:session.save_path="N;/save_path",N 為分級的級數,save_path 為開始目錄。當寫入 SESSION 資料的時候,PHP 會獲取到用戶端的 SESSION_ID,然後根據這個 SESSION ID 到指定的 SESSION 檔保存目錄中找到相應的 SESSION 檔,不存在則創建之,最後將資料序列化之後寫入檔。讀取 SESSION 資料是也是類似的操作流程,對讀出來的資料需要進行解序列化,生成相應的 SESSION 變數。


首先,說明下session_set_save_handler()裡面的每個函數。記住一點:session資料都是在你的程式運行完後才寫入

function open($save_path, $session_name) {
//打開session檔,用來設計保存路徑,一般直接return true 就好了
//在session_start()中會調用到。
}
function close() {
//關閉session連接
}
function read($id) {
//讀取session數據,在session_start()中調用。
}
function write($id, $sess_data) {
//寫session到檔或者資料庫
//記住$_SESSION['var']='test'這種對session賦值並不調用該方法。該方法是在代碼結束後或者調用session_write_close()調用的時候才運行的。
}
function destroy($id) {
//登出session,刪除一條session記錄
}
function gc($maxlifetime) {
//刪除過時的session記錄
}
?>


建立 session.php

資料查詢來源

http://www.phpobject.net/blog/read.php/105.htm