前端學PHP之會話Session

前面的話

  Session技術和Cookie類似,都是用來儲存使用者的相關資料。但最大的不一樣之處在於Cookie是將數據存放在客戶端的計算機之中,而Session則是將數據存放於服務器系統之下。Session的中文意思是會話,在Web系統中,一般是指用戶與Web系統的對話過程。本文將詳細介紹Session的內容php

 

Session ID

  在Web技術發展史上,雖然Cookie技術的出現是一個重大的變革,但Cookie是在客戶端的計算機中保存資料,因此引發了一個爭議。用戶有權阻止Cookie的使用,使Web服務器沒法經過Cookie來跟蹤用戶信息。而Session技術是將使用者相關的資料存放在服務器的系統之下,因此使用者沒法中止Session的使用html

  Session在客戶端僅須要保存由服務器爲用戶建立的一個Session標識符,稱爲Session ID,而在服務器端(文件或數據庫或MemCache中)保存Session變量的值。Session ID是一個既不會重複,又不容易被找到規律的,由32位16進制數組成的字符串mysql

  Session ID會保存在客戶端的Cookie中,若是用戶阻止Cookie的使用,則能夠將Session ID保存在用戶瀏覽器地址欄的URL中。當用戶請求Web服務器時,就會把Session ID發送給服務器,再經過Session ID提取保存在服務器中的Session變量。能夠把Session中保存的變量,當作是這個用戶的全局變量,同一個用戶對每一個腳本的訪問都共享這些變量web

  當某個用戶向Web服務器發出請求時,服務器首先會檢查這個客戶端的請求裏是否已經包含了一個Session ID。若是包含,說明以前已經爲此用戶建立過Session,服務器則按該Session ID把Session檢索出來使用。若是客戶端請求不包含Session ID,則爲該用戶建立一個Session,而且生成一個與此Session相關聯的Session ID,在本次響應中被傳送給客戶端保存sql

【session_start()】數據庫

  用戶向Web服務器發出請求時,必須首先使用session_start()函數來啓動新會話或者重用現有會話,成功開始會話返回TRUE,反之返回FALSE數組

bool session_start ([ array $options = [] ] )

  由於基於Cookie的Session是在開啓的時候,調用session_start()函數會生成一個惟一的SessionID,須要保存在客戶端電腦的Cookie中,和setCookie()函數同樣,調用以前不能有任何的輸出,空格或空行也不行瀏覽器

  若是已經開啓過Session,再次調用Session_start()函數時,不會再建立個新的Session ID。由於當用戶再次訪問服務器時,該函數會經過從客戶端攜帶過來的Session ID,返回已經存在的Session。因此在會話期間,同一個用戶在訪問服務器上任何一個頁面時,都是使用同一個 Session ID緩存

session_start();

  並且,使用session_start()方法會在服務器端創建一個同名的Session文件(文本文件)安全

  若是不想在每一個腳本都使用Session_start()函數來開啓Session,能夠在php.ini裏設置"session.auto_start=1",則無須每次使用Session以前都要調用session_start()函數。但啓用該選項也有一些限制,則不能將對象放入Session中,由於類定義必須在啓動Session以前加載。因此不建議使用php.ini中的session.auto_start屬性來開啓Session

 

讀寫session

  使用session_start()方法啓動session會話後,要經過訪問$_SESSION數組來讀寫session。和$_POST、$_GET、$_COOKIE相似,$_SESSION也是超全局數組

  使用$_SESSION數組將數據存入同名Session文件中

<?php
session_start();
$_SESSION['username'] = 'huochai';
$_SESSION['age'] = 28;
?>

  同名Session文件能夠直接使用文本編輯器打開,該文件的內容結構以下所示:

變量名|類型:長度:值;

<?php
session_start();
print_r ($_SESSION);//Array ( [username] => huochai [age] => 28 )
?>

  Session變量會被保存在服務器端的某個文件中,該文件的位置是經過php.ini文件,在session.save_path屬性指定的目錄下

 

配置Session

  在PHP配置文件php.ini中,有一組和Session相關的配置選項。經過對一些選項從新設置新值,就能夠對Session進行配置,不然使用默認的Session配置

phpinfo();
複製代碼
session.auto_start=0;在請求啓動時初始化session
session.cache_expire=180;設置緩存中的會話文檔在n分鐘後過期
session.cookie_lifetime=0;設置cookie保存時間(s),至關於設置Session過時時間,爲0時表示直到瀏覽器被重啓
session.cookie_path=/;cookie的有效路徑
session.cookie_domain=;cookie的有效域
session.name=PHPSESSID;用在cookie裏的session的名字
session.save_handler=files;用於保存/取回數據的控制方式
session.save_path=/tmp;在save_handler設爲文件時傳給控制器的參數,這是數據文件將保存的路徑.
session.use_cookies=1;是否使用cookies
複製代碼

 

銷燬Session

  當使用完一個Session變量後,能夠將其刪除,當完成一個會話後,也能夠將其銷燬。若是用戶想退出Web系統,就須要提供一個註銷的功能,把全部信息在服務器中銷燬。銷燬和當前Session有關的全部的資料,能夠調用session_destroy()函數結束當前的會話,並清空會話中的全部資源

【session_destroy()】

bool session_destroy ( void )    

  session_destroy()銷燬當前會話中的所有數據,刪除同名Session文件,可是不會重置當前會話所關聯的全局變量,也不會重置會話cookie。若是須要再次使用會話變量,必須從新調用session_start()函數

<?php
session_start();
session_destroy();
?>

  可使用unset()函數來釋放在Session中註冊的單個變量

print_r ($_SESSION);//'Array ( [username] => huochai [age] => 28 )'
unset($_SESSION['username']);
unset($_SESSION['age']);
print_r ($_SESSION);//'Array()'

  [注意]不要使用unset($_SESSION)刪除整個$_SESSION數組,這樣將不能再經過$_SESSION超全局數組註冊變量了

  若是想把某個用戶在Session中註冊的全部變量都刪除,能夠直接將數組變量$_SESSION賦值爲一個空數組

$_SESSION=array();    

  PHP默認的Session是基於Cookie的,Session ID被服務器存儲在客戶端的Cookie中,因此在註銷Session時也須要清除Cookie中保存的SessionID,而這就必須藉助setCookie()函數完成。在Cookie中,保存Session ID的Cookie標識名稱就是Session的名稱,這個名稱是在php.ini中,經過session.name屬性指定的值。在PHP腳本中,能夠經過調用session_name()函數獲取Session名稱。刪除保存在客戶端Cookie中的Session ID

if(isset($_COOKIE[session_name()])) {
    setCookie(session_name(),'',time()-3600);
}

  經過前面的介紹能夠總結出來,Session的註銷過程共須要四個步驟

複製代碼
<?php
//第一步:開啓Session並初始化
session_start();

//第二步:刪除全部Session的變量,也可用unset($_SESSION[xxx])逐個刪除
$_SESSION = array();

//第三步:若是使用基於Cookie的Session,使用setCooike()刪除包含Session Id的Cookie
if (isset($_COOKIE[session_name()])) {
    setcookie(session_name(),'', time()-42000);
}

//第四步:最後完全銷燬Session,刪除服務器端保留session信息的文件
session_destroy();
?>
複製代碼

 

自動回收

  若是沒有經過上述步驟銷燬Session,而是直接關閉瀏覽器,或斷網等狀況,在服務器端保存的Session文件是不會被刪除的。由於在php.ini配置文件中,默認的session.cookie_lifetime=0,表示Session ID在客戶端Cookie的有效期限爲直到關閉瀏覽器。Session ID消失了,但服務器端保存的Session文件並無被刪除。因此,沒有被Session ID關聯的服務器端Session文件成爲了垃圾,而系統則提供了自動清理的機制

  服務器保存的Session文件是普通文本文件,都有文件修改時間。經過在php.ini配置文件中設置session.gc_maxlifetime選項來設置一個到期時間(默認爲1440秒,即24分鐘)。垃圾回收程序在全部Session文件中排查出大於24分鐘的文件。若是用戶還在使用該文件,那麼這個Session文件的修改時間就會被更新,將不會被排查到

  排除出來後,並不會馬上清理垃圾,而是根據配置文件php.info中session.gc_probability/session.gc_divisor這兩個值的比例來決定什麼時候清理,默認值是1/100。表示排查100次,纔有一次可能會啓動垃圾回收機制,來自動回收垃圾。固然,這個值是能夠修改的,但仍是要兼顧服務器的運行性能和存儲空間

 

傳遞session

  使用Session跟蹤一個用戶,是經過在各個頁面之間傳遞惟一的Session ID,並經過Session ID提取這個用戶在服務器中保存的Session變量。常見的Session ID傳送方法有如下兩種

  一、基於Cookie的方式傳遞Session ID。這種方法更優化,但因爲不老是可用,由於用戶在客戶端能夠屏蔽Cookie

  二、經過URL參數進行傳遞,直接將會話ID嵌入到URL中去

  在Session的實現中一般都是採用基於Cookie的方式,客戶端保存的Session ID就是一個Cookie。當客戶禁用Cookie時,Session ID就不能再在Cookie中保存,也就不能在頁面之間傳遞,此時Session失效。不過PHP5在Linux平臺能夠自動檢查Cookie狀態,若是客戶端將它禁用,則系統自動把Session ID附加到URL上傳送。而使用Windows系統做爲Web服務器則無此功能

【經過Cookie傳遞Session ID】

  若是客戶端沒有禁用Cookie,則在PHP腳本中經過session_start()函數進行初始化後,服務器會自動發送HTTP標頭將Session ID保存到客戶端電腦的Cookie中
相似於下面的設置方式

//虛擬向Cookie中設置Session ID的過程
setCookie(session_name(),session_id(),0,'/')

  第一個參數中調用session_name()函數,返回當前Session的名稱做爲Cookie的標識名稱。Session名稱的默認值爲PHPSESSID,是在php.ini文件中由session.name選項指定的值。也能夠在調用session_name()函數時提供參數改變當前Session的名稱

echo session_name();//PHPSESSID

  第二個參數中調用session_id()函數,返回當前Session ID做爲Cookie的值。也能夠經過調用session_id()函數時提供參數設定當前Session ID

echo session_id();//kstvdmae177qqk6jgvg6td12l1

  第三個參數的值0,是經過在php.ini文件中由session.cookiejifetime選項設置的值。默認值爲0,表示SessIon ID將在客戶機的Cookie中延續到瀏覽器關閉

  最後一個參數'/',也是經過PHP配置文件指定的值,在php.ini中由session.cookie.path選項設置的值。默認值爲'/',表示在Cookie中要設置的路徑在整個域內都有效

  若是服務器成功將Session ID保存在客戶端的Cookie中,當用戶再次請求服務器時,就會把Session ID發送回來。因此當在腳本中再次使用session_start()函數時,就會根據Cookie中的Session ID返回已經存在的Session

【經過URL傳遞Session ID】

  若是客戶瀏覽器支持Cookie,就把Session ID做爲Cookie保存在瀏覽器中。但若是客戶端禁止Cookie的使用,瀏覽器中就不存在做爲Cookie的Session ID,所以在客戶請求中不包含Cookie信息。若是調用session_start()函數時,沒法從客戶端瀏覽器中取得做爲Cookie的Session ID,則又建立了一個新的Session ID,也就沒法跟蹤客戶狀態。所以,每次客戶請求支持Session的PHP腳本,session_start()函數在開啓Session時都會建立一個新的Session,這樣就失去了跟蹤用戶狀態的功能

  若是客戶瀏覽器不支持Cookie,PHP則能夠重寫客戶請求的URL,把Session ID添加到URL信息中。能夠手動地在每一個超連接的URL中都添加一個Session ID,但工做量比較大,不建議使用這種方式。以下所示:

<?php
    session_start();
    echo '<a href="demo.php?'.session_name().'='.session_id() .'">連接演示</a>';
?>

  在使用Linux系統作服務器時,而且選用PHP4.2之後的版本,則在編輯PHP時若是使用了-enable-trans-sid配置選項,和運行時選項session.use_trans_sid都被激活,在客戶端禁用Cookie時,相對URL將被自動修改成包含會話ID。若是沒有這麼配置,或者使用Windows系統做爲服務器時,可使用常量SID。該常量在會話啓動時被定義,若是客戶端沒有發送適當的會話Cookie,則SID的格式爲session_name=session_id,不然就爲一個空字符串。所以能夠無條件地將其嵌入到URL中去。以下所示

//當阻止cookie時,SID返回'PHPSESSID=p2qouo8hjarul0a0ii5jmocmc0',不然返回一個空字符串
echo SID;
複製代碼
<?php
    session_start();
    $_SESSION["usemame"]="admin";
    echo "Session ID:".session_id()."<br>";
?>
<a href="test2.php?<?php echo SID ?>">經過URL傳遞Session ID</a>
複製代碼

  若是使用Linux系統做爲服務器,並配置好相應的選項,就不用手動在每一個URL後面附加SID,相對URL將被自動修改成包含Session ID。但要注意,非相對的URL被假定爲指向外部站點,所以不能附加SID。由於這多是個安全隱患,會將SID泄露給不一樣的服務器

 

自定義Session

  在系統中使用Session技術跟蹤用戶時,Session默認的處理方式是使用Web服務器中的文件來記錄每一個用戶的會話信息,經過php.ini中的session_save_path建立會話數據文件的路徑。這種默認的處理方式雖然很方便,但也有一些缺陷。例如,登陸用戶若是很是大,文件操做的I/O開銷就會很大,會嚴重影響系統的執行效率。另外,最主要的是自己的session機制不能跨機,由於對於訪問量比較大的系統,一般都是採用多臺web服務器進行併發處理,若是每臺web服務器都各自獨立地處理Session,就不可能達到跟蹤用戶的目的。這時就須要改變session的處理方式,常見的跨機方法就是經過自定義session的存儲方式,能夠將session信息使用NFS或SAMBA等共享技術保存到其餘服務器中,或使用數據庫來保存session信息,最優的方式是使用memcached來進行session存儲

  不管是用memcached、數據庫、仍是經過NFS或SAMBA共享session信息,其原理是同樣的,都是經過PHP中的session_set_save_handler()函數來改變默認的處理方式,指定回調函數來自定義處理

Session_set_save_hander(callback open,callback close,call read,callback write,callback destro,callback gc);

  該函數共須要6個回調函數做爲必選參數,分別表明了Session生命週期中的6個過程,用戶經過自定義每一個函數,來設置Session生命週期中每一個環節的信息處理

  回調函數的執行時機以下所示

複製代碼
回調函數        描述 
open          運行session_start()時執行,該函數須要聲明兩個參數,系統自動將php.ini中的session_save_path選項值傳遞給該函數的第一個參數,將Session名自動傳遞給第二個參數中,返回true則能夠繼續向下執行
close         該函數不須要參數,在腳本執行完成或調用session_write_close()、session_destroy()時被執行,即在全部session操做完成後被執行。若是不須要處理,則直接返回true便可 
read          在運行session_start()時執行,由於在開啓會話時,會read當前session數據並寫入$_SESSION變量。須要聲明一個參數,系統會自動將Session ID傳遞給該函數,用於經過Session ID獲取對應的用戶數據,返回當前用戶的會話信息寫入$_SESSION變量
write         該函數在腳本結束和對$_SESSION變量賦值數據時執行。須要聲明兩個參數,分別是Session ID和串行化後Session信息字符串。在對$_SESSION變量賦值時,就能夠經過Session ID找到存儲的位置,並將信息寫入。存儲成功能夠返回true繼續向下執行
destroy       在運行session_destroy()時執行,須要聲明一個參數,系統會自動將Session ID傳遞給該函數,去刪除對應的會話信息
gc            垃圾回收程序啓動時執行。須要聲明一個參數,系統自動將php.ini中的session_gc_maxlifetime選項值傳給該函數,用於刪除超過這個時間的Session信息,返回true則能夠繼續向下執行
複製代碼

  在運行session_start()時分別執行了open(啓動會話)、read(讀取session數據至$_SESSION)和gc(清理垃圾),腳本中全部對$_SESSION的操做均不會調用這些回調函數。在調用session_destroy()函數時,執行destroy銷燬當前session(通常是刪除相應的記錄或文件),但此回調函數銷燬的只是Session的數據,此時若是輸出$_SESSION變量,仍然有值,但此值不會再close後被寫回去。在調用session_write_close()函數時執行write和close,保存$_SESSION至存儲,若是不手工使用此方法,則會在腳本結束時被自動執行

  [注意]session_set_save_hander()函數必須在php.ini中設置session_save_hander選項的值爲」user」時(用戶自定義處理器),纔會被系統調用

複製代碼
<?php
    $sess_save_path ="";
    function open($save_path,$session_name){
        global $sess_save_path; 
        $sess_save_path = $save_path;
        return true; 
    }  
    function close(){
        return true; 
    }
    function read($id){
        global $sess_save_path;  
        $sess_file ="{$sess_save_path}/sess_{$id}"; 
        return (string) @file_get_contents($sess_file); 
    }
    function write($id,$sess_data){
        global $sess_save_path;  
        $sess_file ="{$sess_save_path}/sess_{$id}"; 
        if($fp=@fopen($sess_file,"w")){   
            $return = fwrite($fp,$sess_data);
            fclose($fp); 
            return $return; 
        }else{  
            return false; 
        } 
    }  
    function destroy($id){ 
        global $sess_save_path;  
        $sess_file ="{$sess_save_path}/sess_{$id}"; 
        return (@unlink($sess_file)); 
    }   
    function gc($maxlifetime){  
        global $sess_save_path;     
        foreach(glob("{$sess_save_path}/sess_*") as $filename){ 
            if(filemtime($filename) + $maxlifetime <time() ){ 
                @unlink($filename); 
            } 
        }   
        return true; 
    } 
    session_set_save_hander(「open","close","read","write","destroy","gc");
    session_start();
?>
複製代碼

 

數據庫處理

  若是網站訪問量很是大,須要採用負載均衡技術搭載多臺Web服務器協同工做,就須要進行Session同步處理。使用數據庫處理Session會比使用NFS及SAMBA更佔優點,能夠專門創建一個數據庫服務器存放Web服務器的Session信息,當用戶無論訪問集羣中的哪一個Web服務器,都會去這個專門的數據庫,訪問本身在服務器端保存的Session信息,以達到Session同步的目的。另外,使用數據庫處理Session還能夠給咱們帶來不少好處,好比統計在線人數等。若是mysql也作了集羣,每一個mysql節點都要有這張表,而且這張Session表的數據要實時同步

  在使用默認的文件方式處理Session時,有3個比較重要的屬性,分別是文件名稱、文件內容及文件的修改時間:經過文件名稱中包含的Session ID,用戶能夠找到本身在服務器端的Session文件;經過文件內容用戶能夠在各個腳本中存取$_session變量;經過文件的修改時間則能夠清除全部過時的Session文件。因此使用數據表處理Session信息,也最少要有這三個字段(Session ID、修改時間、Session內容信息),固然若是考慮更多的狀況,例如,用戶改變了IP地址,用戶切換了瀏覽器等,還能夠再自定義一些其餘字段。下面爲Session設計的數據表結構包含5個字段,建立保存Session信息表session的SQL語句以下所示:

複製代碼
CREATE TABLE session(
    sid CHAR(32) NOT NULL DEFAULT '',
    update INT NOT NULL DEFAULT 0,
    client_ip CHAR(15) NOT NULL DEFAULT '',
    user_agent CHAR(200) NOT NULL DEFAULT '',
    data TEXT,
    PRIMARY KEY(sid)
);
複製代碼

  數據表session建立成功後,再經過自定義的處理方式,將Session信息寫入到數據庫中

複製代碼
<?php
class DBSession {
    public static $pdo;             //pdo的對象
    public static $ctime;           //當前時間
    public static $maxlifetime;     //最大的生存時間
    public static $uip;             //用戶正在用的ip
    public static $uagent;          //用戶正在用的瀏覽器

    //開啓和初使化使用的, 參數須要一個路
    public static function start(PDO $pdo) {
        
        self::$pdo = $pdo;
        self::$ctime = time();
        self::$maxlifetime = ini_get("session.gc_maxlifetime");
        self::$uip = !empty($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : (!empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "") );

        filter_var(self::$uip, FILTER_VALIDATE_IP) && self::$uip = '';
        self::$uagent = !empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : "" ;

        //註冊過程, 讓PHP本身處理session時,找這個函數指定的幾個週期來完成
        session_set_save_handler(
            array(__CLASS__, "open"), 
            array(__CLASS__,"close"),
            array(__CLASS__, "read"), 
            array(__CLASS__, "write"),
            array(__CLASS__, "destroy"), 
            array(__CLASS__,"gc"));
        session_start();  //開啓會話
    }

    // 開啓時, session_start()
    public static function open($path, $name) {
        return true;
    }

    //關閉
    public static  function close() {
        return true;
    }

    //讀取 echo $_SESSION['username'] 
    public static  function read($sid) {
        $sql = "select * from session where sid = ?";
        $stmt = self::$pdo -> prepare($sql);
        $stmt -> execute(array($sid));
        $result = $stmt -> fetch(PDO::FETCH_ASSOC);
        //若是尚未會話信息,返回空字符串
        if(!$result) {
            return '';
        }
        //若是超出時間,銷燬session
        if($result['utime'] + self::$maxlifetime < self::$ctime) {
            self::destroy($sid);
            return '';
        }
        //若是用戶換了ip或換了瀏覽器
        if($result['uip'] != self::$uip || $result['uagent'] != self::$uagent) {
            self::destroy($sid);
            return '';
        }
        return $result['sdata'];

    }

    //寫入 $_SESSION['username'] = "meizi";
    public static  function write($sid, $data) {

        //經過sid獲取已經有的數據
        $sql = "select * from session where sid = ?";
        $stmt = self::$pdo->prepare($sql);
        $stmt -> execute(array($sid));
        $result = $stmt -> fetch(PDO::FETCH_ASSOC);
        
        //若是已經獲取到了數據,就不插入而更新
        if($result) {
            //若是數據和原來的不一樣才更新
            if($result['sdata'] != $data || $result['utime']+10 < self::$ctime) {
                $sql = "update session set sdata = ?, utime = ? where sid=?";
                $stmt = self::$pdo->prepare($sql);
                $stmt -> execute(array($data, self::$ctime, $sid));
            }

        //若是沒有數據,就新插入一條數據
        } else {
        
            if(!empty($data)) {
                $sql = "insert into session(sid, sdata, utime, uip, uagent) values(?, ?, ?, ?, ?)";
                $stmt = self::$pdo -> prepare($sql);
                $stmt -> execute(array($sid, $data, self::$ctime, self::$uip, self::$uagent));
            }
        }

    }

    //銷燬 session_destroy() 
    public static  function destroy($sid) {
        $sql = "delete from session where sid=?";
        $stmt = self::$pdo->prepare($sql);
        return $stmt -> execute(array($sid)); 
    }

    //回收垃圾
    public static  function gc($maxlifetime) {
        //    utime < ctime - self::$maxlifetime
        $sql = "delete from session where utime < ?";
        $stmt = self::$pdo->prepare($sql);
        return $stmt -> execute(array(self::$ctime - self::$maxlifetime));     
    }
}
    //開啓
    DBSession::start($pdo);
複製代碼

 

memcached處理

  用數據庫來同步Session會加大數據庫的負擔,由於數據庫原本就是容易產生瓶頸的地方,但若是採用MemCache來處理Session是很是合適的,由於MemCache的緩存機制和Session很是類似。另外,MemCach能夠作分佈式,可以把Web服務器中的內存組合起來,成爲一個」內存池」,不論是哪一個服務器產生的Session,均可以放到這個「內存池」中,其餘的Web服務器均可以使用。以這種方式來同步Session,不會加大數據庫的負擔,而且安全性也要比使用Cookie高。把session放到內存裏面,讀取也要比其餘處理方式快不少

  自定義使用memcached處理session信息,和自定義數據庫的處理方式相同,但要簡單得多,由於MemCache的工做機制和Session技術很類似

複製代碼
<?php

class MemSession {
    public static $mem;             //pdo的對象
    public static $maxlifetime;     //最大的生存時間

    public static function start(Memcache $mem) {    
        self::$mem = $mem;    
        self::$maxlifetime = ini_get("session.gc_maxlifetime");
    
        //註冊過程, 讓PHP本身處理session時,按照這個函數指定的幾個週期來完成
        session_set_save_handler(
            array(__CLASS__, "open"), 
            array(__CLASS__,"close"),
            array(__CLASS__, "read"), 
            array(__CLASS__, "write"),
            array(__CLASS__, "destroy"), 
            array(__CLASS__,"gc"));
        session_start();  //開啓會話
    }

    // 開啓時,session_start()
    public static function open($path, $name) {
        return true;
    }

    //關閉
    public static  function close() {
        return true;
    }

    //讀取 echo $_SESSION['username'] 
    public static  function read($sid) {
        $data = self::$mem -> get($sid);
        if(empty($data)) {
            return '';
        }
        return $data;
    }

    //寫入
    public static  function write($sid, $data) {
        self::$mem -> set($sid, $data, MEMCACHE_COMPRESSED, self::$maxlifetime);
    }

    //銷燬 session_destroy() 
    public static  function destroy($sid) {
        self::$mem -> delete($sid, 0);

    }

    //回收垃圾
    public static  function gc($maxlifetime) {
        return true;    
    }
}
    //建立對象
    $mem = new Memcache();
    //添加兩臺memcache服務器
    $mem -> addServer("localhost", 11211);
    $mem -> addServer("192.168.1.3", 11211);
    //開啓
    MemSession::start($mem);
?>
複製代碼
相關文章
相關標籤/搜索