php session工作原理

在客戶端登錄網站時,被訪問的PHP頁面可以使用session_start()打開session,這樣就會產生客戶端的唯一標識session id(可以通過session_id()獲取/設置)Session id可以通過兩種方式保留在客戶端。一種是自動加入到geturl中,或者POST的表單中,默認情況下變量名爲PHPSESSID;另一種是通過COOKIE,,默認情況下,這個COOKIE的名字爲PHPSESSID.

多服務器共享session

必須實現兩個目標:一個是各個服務器對同一個客戶端產生的session id必須相同,並且可通過同一個cookie進行傳遞,也就是說各個服務器必須可以讀取同一個名爲PHPSESSIDCOOKIE;另一個是session數據的存儲方式/位置必須保證各個服務器都能夠訪問到,簡單地說就是多服務器共享客戶端的session id,同時還必須共享服務器端的session數據。

實現方案

首先創建數據庫表

Create table sess(

'sesskey' varchar(32) not null default '',

'expiry' bigint(20) not null default "0",

'data' longtext not null,

primary key ('sesskey'),

key 'expiry' ('expiry')

)type=MyISAM;

sesskeySESSION ID,expirysession過期時間,data用於保存session數據

默認情況下session數據是以文件方式保存,想要使用數據庫方式保存,就必須重定義SESSION各個操作的處理函數。Php提供了session_set_save_handle()函數,可以用此函數自定義session處理過程,首先要先將session.save_handler改成user.php中進行設置

Session_module_name('user')

Session_module_name()見幫助文檔

面向對象的代碼:

<?php

define('MY_SESS_TIME',3600);//SESSION生存時間

//類定義

Class My_Sess

{

function init()

{

$domain = '.inform.com';

ini_set("session.use_trans_sid",0);//不使用get/post變量方式

ini_set('session.gc_maxlifetime',MY_SESS_TIEME);//session生存時間

ini_set("session.user_cookies",1);//使用cookie保存session id的方式

ini_set("session.cookie_path","/");

ini_set("session.cookie_domain",$domian);//多主機共享保存session idcookie

session_module_name('user');//session.save_handler設置爲user,默認爲files

session_set_save_handler(//定義session各項操作所對應的方法名

array("My_Sess","open"),//對應於靜態方法My_Sess::open()下同

array("My_Sess","close"),

array("My_Sess","read"),

array("My_Sess","write"),

array("My_Sess","destroy"),

array("My_Sess","gc"),

);

}

function open($save_path,$session_name)

{

return true;

}

function close()

{

global $MY_SESS_CONN;

if($MY_SESS_CONN)

{

$MY_SESS_CONN->Close();//關閉數據連接

}

return true;

}

funcion read($sesskey)

{

global $MY_SESS_CONN;

$sql = "select data from sess where sesskey=".$MY_SESS_CONN->qstr($sesskey)." and expiry>=".time();

$rs = &$MY_SESS_CONN->Execute($sql);

if($rs)

{

return '';

}

else

{

$v =$rs->fields[0];

$rs->close();

return $v;

}

return '';

 }

function write($sesskey,$data)

{

global $MY_SESS_CONN;

$qkey = $MY_SESS_CONN->qstr($sesskey);

$expiry = time() + My_SESS_TIME;//設置過期時間

$arr = array(//寫入session
            "sesskey" => $qkey,
            "expiry" => $expiry,
            "data"    => $data);
        $MY_SESS_CONN->Replace("sess", $arr, "sesskey", $autoQuote = true);
        return true;

}

function destroy($sesskey) {
        global $MY_SESS_CONN;

        $sql = "DELETE FROM sess WHERE sesskey=".$MY_SESS_CONN->qstr($sesskey);
        $rs =& $MY_SESS_CONN->Execute($sql);
        return true;
    }

function gc($maxlifetime = null) {
        global $MY_SESS_CONN;

        $sql = "DELETE FROM sess WHERE expiry<".time();
        $MY_SESS_CONN->Execute($sql); //由於經常性的對錶 sess 做刪除操作,容易產生碎片 
        $sql = "OPTIMIZE TABLE sess"; //所以在垃圾回收中對該表進行優化操作。
        $MY_SESS_CONN->Execute($sql);
        return true;
    } 

}

/使用 ADOdb 作爲數據庫抽象層。
require_once("adodb/adodb.inc.php");
//數據庫配置項,可放入配置文件中(如:config.inc.php)。
$db_type = "mysql";
$db_host = "192.168.212.1";
$db_user = "sess_user";
$db_pass = "sess_pass";
$db_name = "sess_db";
//創建數據庫連接,這是一個全局變量。
$GLOBALS["MY_SESS_CONN"] =& ADONewConnection($db_type);
$GLOBALS["MY_SESS_CONN"]->Connect( $db_host, $db_user, $db_pass, $db_name);
//初始化 SESSION 設置,必須在 session_start() 之前運行!!
My_Sess::init();
?>


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章