萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> php編程 >> PHP4的session功能

PHP4的session功能

 這篇文章描述了怎樣定制php4的session處理。我們提供一個怎樣寫一個全功能的基於mysql數據庫或dbm文件的session處理程序例子。 


一、序言 


新的php4有一套自己的session處理函數。缺省情況下,每個session存貯在系統臨時目錄的一個個獨立文件中(例如在unix系統中為/tmp)。 

這適合或不適合,依你的需求而言。例如:如果你的支持php的web服務器分布在不同的機器上,你不能很容易地共享它們之間的session(當然,你也可以將sessions保存在NFS共享中)。另一個潛在的問題是你機器上的數千或數百萬個session文件使你的文件系統變得散亂 。 

對我們來說幸運的是,php4的開發者非常有遠見(感謝他們),他們為你我這樣的用戶提供了擴展session處理的接口。 


這個文檔解釋一點session的處理並且提供兩個能夠工作的怎樣擴展session處理的例子。我們的第一個例子將使session處理程序保存 session數據到DBM文件中。我們的第二個例子將保存session數據到MYSQL數據庫中。 

在你開始之前,請下載ying20000602.zip 並且將它解開放到web文檔目錄中。(我已經將它帶在本文的結尾處了) 

任何一個我們寫的session處理程序會提供6個基本的函數,它們將被php4的session處理程序調用,所以你不用擔心怎樣調用它們。 

好在這些定制處理session的函數對你來說是完全透明的。所以你可以改動它們而不會影響你自己的PHP腳本。 


這幾個函數是: 

sess_open($sess_path, $session_name); 


這個函數被session處理程序調用來作初始化工作。需要傳給它的兩個參數是$sess_path,它對應你的php.ini文件中的session.save_path選項;$session_name,它對應php.ini中的session.name選項。它們具體怎樣工作,請看下面的例子。 


sess_close(); 


這個函數在頁面結束執行並且session處理程序需要關閉時被調用。(注意,不要和sess_destory混淆了,它是用來結束session的) 


sess_read($key); 


這個函數在session處理程序讀取指定session鍵值($key)時。 

這個函數檢索並返回標識為$key的session數據.(注意:你不用擔心怎樣序列化和反序列化數據,如果你不知道這是什麼意思,不要擔心它) 


譯者注:序列化是將變量或對象在程序結束或需要時保存在文件中,在下次程序運行或需要時再調入內存的技術,有別於只保存數據的方法。 


sess_write($key, $val); 


這個函數據在session處理程序需要將數據保存時調用,這種情況經常在你的程序結束時發生。 

它負責將數據保存在下次能用sess_read($key)函數檢索的地方。 


sess_destroy($key); 


這個函數在需要消毀session時。它負責刪除session並且清除環境。 


sess_gc($maxlifetime); 

這個函數負責清理碎片。在這種情況下,它負責刪除過時的session數據。session處理程序會偶爾調用它們。 


現在我們已經清楚了我們提供的函數。它們不是非要這樣命名,但必須接受這些參數。(不管你需不需要它們) 


DBM session 處理程序 


我們的第一個范例是寫一個保存session數據到DBM文件中的定制session處理程序。(這是ying20000602.zip中的session_dbm.php文件) 


有很多充足的理由讓你要這樣做,例如,如果你在isp那兒有一台共享的服務器(譯注:相當於我們說的虛擬主機吧)並且你不想讓你的session數據 


和別人的混在一起。 


重要注釋: 

在你試驗這些程序時你的php4必須有DBM支持。如果不是這樣的(譯注:如果沒有DBM支持)會很難看,真的很難看! 

我們要做的這些工作將會得到一個所有session數據的DBM文件。(萬一你不知道,DBM文件象一個僅保存"鍵/值"對的非常簡單的數據庫. 

由下面的6個函數據實現: 


sess_open($sess_path, $session_name); 

我們將調用dbmopen()打開一個處於讀寫模式的DBM文件。我們的DBM文件將被命名為/tmp/PHPSESSID,除非你修改了php.ini中的session路 

徑和名字設置。 


sess_close(); 

在這個函數中,我們將簡單地調用dbmclose()函數關閉DBM文件。 


sess_read($key); 

這兒我們僅僅調用dbmfetch()載入和參數$key相關連的session數據。 

在載入一個session時,我們需要保證讀入的不是一個過期數據,所以我們必須給session配上一個時間標記。 


為什麼?因為在它們失效,不管什麼原因而沒有被刪掉時,我們不會意外地讀入過期數據。這會是一個很大的禁忌。 


我們知道DBM文件只保存 鍵/值 對,因此不得不在寫session數據時將時間標記同" 值"一起寫入,在讀session數據時去掉。 


任何已經過期的session將被忽略。看看這個源程序,它會讓你更清楚。 

 

sess_write($key, $val); 

寫入一個session,我們會使用dbmreplace()函數。注意,從上所述我們要保存過期時間標記在session中,所以我們要將時間標記綁到值上。 


sess_destroy($key); 

消毀一個session很容易,我們只需要調用dbmdelete()函數將它從session文件中刪除。 


sess_gc($maxlifetime); 

過期數據收集在這兒有點令人討厭但卻是必需的,為了達到目的我們在循環掃描所有保存在DBM文件中的session並且刪掉過期的。這會很慢因 

為我們循環通過所有保存在這個文件中的所有session數據。 


現在我們已經有了一個DBM session處理程序,太酷了! 


現在,我們讓這些session保存到mysql數據庫中。 


Mysql session處理程序 

(This 

我們的下一個范例是寫一個將session數據存到mysql數據庫的定制session處理程序。(這個在session_mysql.php文件中,見文章尾部) 

在你有許多支持PHP的服務器並且你需要共享它們之間的session時你會想將session保存在數據庫中的。(比如你服務於很多用戶並且需要 

負載平衡時) 

You have a bunch of machines doing web/PHP stuff, a machine serving 

你有一批機器作支持php的服務器,需要一台機器作你的普通數據庫服務器,另外一台運行mysql數據庫處理session。僅這樣對大多數人來 

說就具有很大的殺傷力的。:)(譯注:可能意思是太酷了吧) 


重要提示: 

在你試驗之前你的php必須支持mysql。(譯注:這好象已經不成問題了,php現在已經內建mysql支持了)如果不是這樣的話,事情會很難看,真的 

很難看。 

首先我們在mysql中創建一個session數據庫,並且創建一個session表。先運行你的mysql客戶端並且運行下面的命令: 

mysql> CREATE DATABASE sessions; 


mysql> GRANT select, insert, update, delete ON sessions.* TO phpsession@localhost 

-> IDENTIFIED BY 'phpsession'; 


mysql> CREATE TABLE sessions ( 

-> sesskey char(32) not null, 

-> expiry int(11) unsigned not null, 

-> value text not null, 

-> PRIMARY KEY (sesskey) 

-> ); 


下一步,修改session_mysql.php文件的$SESS_DB* 變量使其匹配你機器上的數據庫設置。在你繼續之前確信一切看起來良好。 


我們的6個函數會依靠mysql數據庫工作: 


sess_open($sess_path, $session_name); 

我們需要調用mysql_Pconnect(),然後用mysql_selsect_db()選擇session數據庫 。$sess_path 和$session_name 參數 

是無關的但我們不得不保留它們。(譯注:原文如此,可能是為了兼容吧) 


sess_close(); 

我們要打開一個mysql永久連接因此我們在這個函數中不做任何事。(一個空函數) 


sess_read($key); 

這個竅門就是一個簡單的select語句,我們想要讀取所給的$key的session數據,需要指定過期時間信息。 


sess_write($key, $val); 

寫session數據用了一個小把戲。我們首先試圖用insert語句保存session數據到數據庫中。如果失敗(主鍵約束)則意味著這個key已經寫入,然後我們 

不得不用一update語句代替。 


sess_destroy($key); 

刪除一個session很容易,我們只需要從數據庫中刪除這個鍵值。 


sess_gc($maxlifetime); 

處理過期session也很容易,我們只需要從數

copyright © 萬盛學電腦網 all rights reserved