session的聲明與使用
session的設(shè)置不同于cookie,必須先啟動,在php中必須調(diào)用session_start()。session_start()函數(shù)的語法格式如下:
bool session_start(void) //創(chuàng)建session,開始一個會話,進行session初始化
注意:session_start()函數(shù)之前不能有任何輸出
當(dāng)?shù)谝淮卧L問網(wǎng)站時,seesion_start()函數(shù)就會創(chuàng)建一個唯一的session id,并自動通過http的響應(yīng)頭,將這個session id保存到客戶端cookie中。同時,也在服務(wù)器端創(chuàng)建一個以session id命名的文件,用于保存這個用戶的會話信息。當(dāng)同一個用戶再次訪問這個網(wǎng)站時,也會自動通過http的請求頭將cookie中保存的seesion id再攜帶過來,這時session_start()函數(shù)就不會再去分配一個新的session id,而是在服務(wù)器的硬盤中去尋找和這個session id同名的session文件,將這之前為這個用戶保存的會話信息讀出,在當(dāng)前腳本中應(yīng)用,達到跟蹤這個用戶的目的。 session以數(shù)組的形式使用,如:$_session['session名']
注冊一個會話變量和讀取session
在php中使用session變量,除了要啟動之外,還要經(jīng)過注冊的過程。注冊和讀取session變量,都要通過訪問$_session數(shù)組完成。在$_session關(guān)聯(lián)數(shù)組中的鍵名具有和php中普通變量相同的命名規(guī)則。注冊session變量的代碼如下所示:
代碼如下:
<?php
//啟動session的初始化
session_start();
//注冊session變量,賦值為一個用戶的名稱
$_session[username]=skygao;
//注冊session變量,賦值為一個用戶的id
$_session[uid]=1;
?>
執(zhí)行該腳本后,兩個session變量就會被保存在服務(wù)器端的某個文件中,該文件的位置是通過php.ini文件,在session.save_path屬性指定的目錄下。
注銷變量與銷毀session
當(dāng)使用完一個session變量后,可以將其刪除,當(dāng)完成一個會話后,也可以將其銷毀。如果用戶退出web系統(tǒng),就需要為他提供一個注銷的功能,把他的所有信息在服務(wù)器中銷毀。銷毀和當(dāng)前session有關(guān)的所有的資料,可以調(diào)用session_destroy()函數(shù)結(jié)束當(dāng)前的會話,并清空會話中的所有資源。該函數(shù)的語法格式如下所示:
bool session_destroy(void) //銷毀和當(dāng)前session有關(guān)的所有資料
該函數(shù)并不會釋放和當(dāng)前session相關(guān)的變量,也不會刪除保存在客戶端cookie中的session
id。因為$_session數(shù)組和自定義的數(shù)組在使用上是相同的,所以我們可以使用unset()函數(shù)來釋放在session中注冊的單個變量。如下所示:
unset($_session['鍵名']);
一定要注意,不要使用unset($_session)刪除整個$_session數(shù)組,這樣將不能再通過$_session超全局數(shù)組注冊變量了。但如果想把某個用戶在session中注冊的所有變量都刪除,可以直接將數(shù)組變量$_session賦上一個空數(shù)組。如下所示:
$_session=array()
php默認的session是基于cookie的,session
id被服務(wù)器存儲在客戶端的cookie中,所以在注銷session時也需要清除cookie中保存的sessionid,而這就必須借助setcookie()函數(shù)完成。在php腳本中,可以通過調(diào)用session_name()函數(shù)獲取session名稱。刪除保存在客戶端cookie中的session
id,代碼如下所示:
代碼如下:
<?php
//判斷cookie中是否存在session id
if(isset($_cookie[session_name()])){
//刪除包含session id的cookie,注意第四個參數(shù)一定要和php.ini設(shè)置的路徑相同
setcookie(session_name(),'',time()-3600,'/');
}
?>
通過前面的介紹可以總結(jié)出,session的注銷過程共需要4個步驟。在下例中,提供完整的四個步驟代碼,運行該腳本就可以關(guān)閉session,并銷毀與本次會話有關(guān)的所有資源。代碼如下所示:
代碼如下:
<?php
//第一步:開啟session并初始化
session_start();
//第二部:刪除所有session的變量,也可以用unset($_session[xxx])逐個刪除
$_session = array();
//第三部:如果使用基于cookie的session,使用setcookkie()刪除包含session id的cookie
if(isset($_cookie[session_name()])) {
setcookie(session_name(), , time()-42000, /);
}
//第四部:最后徹底銷毀session
session_destroy();
?>
session的phpini配置選項
php.ini文件和session有關(guān)的幾個常用配置選項:
session.auto_start = 0 ; 在請求啟動時初始化session
session.cache_expire = 180 ; 設(shè)置緩存中的會話文檔在 n 分鐘后過時
session.cookie_lifetime = 0 ; 設(shè)置按秒記的cookie的保存時間,相當(dāng)于設(shè)置session的過期時間,為0時表示直到瀏覽器被重啟
session.auto_start=1,這樣就無需每次使用session之前都要調(diào)用session_start()不建議使用.但啟用該選項也有一些限制,如果確實啟用了 session.auto_start,則不能將對象放入會話中,因為類定義必須在啟動會話之前加載以在會話中重建對象。
session.cookie_path = / ; cookie的有效路徑
session.cookie_domain = ; cookie的有效域
session.name = phpsessid; 用在cookie里的session的名字
session.save_handler = files ; 用于保存/取回數(shù)據(jù)的控制方式
session.save_path = /tmp ; 在 save_handler 設(shè)為文件時傳給控制器的參數(shù), 這是數(shù)據(jù)文件將保存的路徑.
session.use_cookies = 1 ; 是否使用cookies
session的垃圾自動回收機制
可以通過session_destroy()函數(shù)在頁面中提供一個“退出”按鈕,通過單擊銷毀本次會話。但如果用戶沒有單擊退出按鈕,而是直接關(guān)閉瀏覽器,或斷網(wǎng)等情況,在服務(wù)器端保存的session文件是不會刪除的。雖然關(guān)閉瀏覽器,下次需要重新分配一個新的session id重新登錄,但這只是因為在php.ini中的設(shè)置seesion.cookie_lifetime=0,來設(shè)定session id在客戶端cookie中的有效限期,以秒為單位指定了發(fā)送到瀏覽器的cookie的生命周期。當(dāng)系統(tǒng)賦予session有效期限后不管瀏覽器是否開啟,session id都會自動消失。而客戶端session id消失服務(wù)器端保存的session文件并沒有被刪除。所以沒有被sessoin id引用的服務(wù)器端session文件,就成為了“垃圾”。
服務(wù)器保存的session文件就是一個普通文本文件,所以都會有文件修改時間。“垃圾回收程序”啟動后就是根據(jù)session文件的修改時間,將所有過期的session文件全部刪除。通過在php.ini中設(shè)置session.gc_maxlifetime選項來指定一個時間(單位:秒),例如設(shè)置該選項值為1440(24分鐘)?!袄厥粘绦颉本蜁谒衧ession文件中排查,如果有修改時間距離當(dāng)前系統(tǒng)時間大于1440秒的就將其刪除。
“session垃圾回收程序”是怎樣的啟動機制呢?“垃圾回收程序”是在調(diào)用session_start()函數(shù)時啟動的。而一個網(wǎng)站有多個腳本,沒有腳本又都要使用session_start()函數(shù)開啟會話,又會有很多個用戶同時訪問,這就很可能session_start()函數(shù)在1秒內(nèi)被調(diào)用n次,而如果每次都會啟動“session垃圾回收程序”,這樣是很不合理的。可以通過php.ini文件中修改“session.gc_probability和session.gc_divisor”兩個選項,設(shè)置啟動垃圾回收程序的概率。會根據(jù)“session.gc_probability/session.gc_divisor”公示計算概率,例如選項session.gc_probability=1,而選項session.gc_divisor=100,這樣的概率就是“1/100”,即session_start()函數(shù)被調(diào)用100次才會有一次可能啟動“垃圾回收程序”。
php.ini中相關(guān)的配置
session.cookie_lifetime=0; 關(guān)閉瀏覽器相應(yīng)的cookie文件即被刪除
session.gc_maxlifetime; 設(shè)置過期session時間,默認1440秒(24分鐘)
session.gc_probability/session.gc_divisor; 啟動垃圾回收機制的概率(建議值為1/1000——5000)
cookie禁用時通過url傳遞session的id
使用session跟蹤一個用戶,是通過在各個頁面之間傳遞唯一的session id,并通過session id提取這個用戶在服務(wù)器中保存的session變量。常見的session id傳送方法有以下兩種。
第一種方法是基于cookie的方式傳遞session id,這種方式更優(yōu),但不總是可用, 因為用戶在客戶端可以屏蔽cokie;
第二種方法是通過url參數(shù)進行傳遞,直接將session id嵌入到url中去。
在session的實現(xiàn)中通常都是采用cookie的方式,客戶端保存的session id就是一個cookie。當(dāng)客戶禁用cookie時,session id就不能在cookie中保存,也就不能在頁面之間傳遞,此時session失效。不過php5在linux平臺可以自動檢查cookie狀態(tài),如果客戶端禁用它,則系統(tǒng)自動把session id附加到url上傳送。而使用windows系統(tǒng)作為web服務(wù)器則無此功能。
在php中提出了跟蹤session的另一種機制,如果客戶瀏覽器不支持cookie,則php可以重寫客戶請求的url,把session id添加到url信息中??梢允謩拥卦诿總€超鏈接的url中都加上一個session id,但工作量比較大,不建議使用這種方法。如下所示:
代碼如下:
<?php
//開啟session
session_start();
//在每個url后面附加上參數(shù),變量名為session_name()獲取名稱,值通過session_id()獲取
echo '<a href=demo.php?'.session_name().'='.session_id().'>連接演示</a>';
?>
在使用linux系統(tǒng)做服務(wù)器時,則在編輯php時如果使用了–enable-trans-sid配置選項,和運行時選項session.use_trans_sid都被激活,在客戶端禁用cookie時,相對url將被自動修改為包含會話id。如果沒有這么配置,或者使用windows系統(tǒng)作為服務(wù)器時,可以使用常量sid。該常量在會話啟動時被定義,如果客戶端沒有發(fā)送適當(dāng)?shù)臅抍ookie,則sid的格式為session_name=session_id,否則就為一個空字符串。因此可以無條件地將其嵌入到url中去。在下例中使用兩個腳本程序,演示了session id的傳送方法。
<?php
session_start();
$_session[username]=admin;
echo session id:.session_id().<br>;
?>
通過url傳遞session id
在腳本test2.php中,輸出test1.php腳本在session變量中保存的另一個用戶名。又在該頁面中輸出一次session id,通過對比判斷兩個腳本是否使用同一個session id。另外,在開啟或關(guān)閉cookie時,注意瀏覽器地址欄中url的變化。代碼如下所示:
代碼如下:
<?php
session_start();
echo $_session[username].< br>;
echo session id:.session_id().<br>;
?>
更多信息請查看IT技術(shù)專欄