php中Session的使用方法

語言: CN / TW / HK

Session的聲明與使用

Session的設置不同於Cookie,必須先啟動,在PHP中必須調用session_start()。session_start()函數的語法格式如下:

  Bool session_start(void) //創建Session,開始一個會話,進行Session初始化
  注意:session_start()函數之前不能有任何輸出

當第一次訪問網站時,Seesion_start()函數就會創建一個唯一的Session ID,並自動通過HTTP的響應頭,將這個Session ID保存到客户端Cookie中。同時,也在服務器端創建一個以Session ID命名的文件,用於保存這個用户的會話信息。

當同一個用户再次訪問這個網站時,也會自動通過HTTP的請求頭將Cookie中保存的Seesion ID再攜帶過來,這時Session_start()函數就不會再去分配一個新的Session ID,而是在服務器的硬盤中去尋找和這個Session ID同名的Session文件,將這之前為這個用户保存的會話信息讀出,在當前腳本中應用,達到跟蹤這個用户的目的。 Session以數組的形式使用,如:$_SESSION['session名']

  註冊一個會話變量和讀取Session

  在PHP中使用Session變量,除了要啟動之外,還要經過註冊的過程。註冊和讀取Session變量,都要通過訪問$_SESSION數組完成。在$_SESSION關聯數組中的鍵名具有和PHP中普通變量相同的命名規則。註冊Session變量的代碼如下所示:

<?php
//啟動session的初始化
session_start();
//註冊session變量,賦值為一個用户的名稱
$_SESSION["username"]="skygao";
//註冊session變量,賦值為一個用户的ID
$_SESSION["uid"]=1;
?>

執行該腳本後,兩個Session變量就會被保存在服務器端的某個文件中,該文件的位置是通過php.ini文件,在session.save_path屬性指定的目錄下。

 註銷變量與銷燬Session

  當使用完一個Session變量後,可以將其刪除,當完成一個會話後,也可以將其銷燬。如果用户退出Web系統,就需要為他提供一個註銷的功能,把他的所有信息在服務器中銷燬。銷燬和當前Session有關的所有的資料,可以調用session_destroy()函數結束當前的會話,並清空會話中的所有資源。該函數的語法格式如下所示:

 bool session_destroy(void) //銷燬和當前Session有關的所有資料

  該函數並不會釋放和當前Session相關的變量,也不會刪除保存在客户端Cookie中的SessionID。因為$_SESSION數組和自定義的數組在使用上是相同的,所以我們可以使用unset()函數來釋放在Session中註冊的單個變量。如下所示:

  unset($_SESSION['鍵名']);

  一定要注意,不要使用unset($_SESSION)刪除整個$_SESSION數組,這樣將不能再通過$_SESSION超全局數組註冊變量了。但如果想把某個用户在Session中註冊的所有變量都刪除,可以直接將數組變量$_SESSION賦上一個空數組。如下所示:

 $_SESSION=array()

  PHP默認的Session是基於Cookie的,SessionID被服務器存儲在客户端的Cookie中,所以在註銷Session時也需要清除Cookie中保存的SessionID,而這就必須藉助setCookie()函數完成。在PHP腳本中,可以通過調用session_name()函數獲取Session名稱。刪除保存在客户端Cookie中的SessionID,代碼如下所示:

<?php
//判斷Cookie中是否存在session ID
if(isset($_COOKIE[session_name()])){
    //刪除包含Session ID的cookie,注意第四個參數一定要和php.ini設置的路徑相同
    setcookie(session_name(),'',time()-3600,'/');
}
?>

通過前面的介紹可以總結出,Session的註銷過程共需要4個步驟。在下例中,提供完整的四個步驟代碼,運行該腳本就可以關閉Session,並銷燬與本次會話有關的所有資源。代碼如下所示:

<?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有關的幾個常用配置選項:

  session.auto_start = 0 ; 在請求啟動時初始化session

  session.cache_expire = 180 ; 設置緩存中的會話文檔在 n 分鐘後過時

  session.cookie_lifetime = 0 ; 設置按秒記的cookie的保存時間,相當於設置Session的過期時間,為0時表示直到瀏覽器被重啟

session.auto_start=1,這樣就無需每次使用session之前都要調用session_start()不建議使用.但啟用該選項也有一些限制,如果確實啟用了 session.auto_start,則不能將對象放入會話中,因為類定義必須在啟動會話之前加載以在會話中重建對象。

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_destroy()函數在頁面中提供一個“退出”按鈕,通過單擊銷燬本次會話。但如果用户沒有單擊退出按鈕,而是直接關閉瀏覽器,或斷網等情況,在服務器端保存的Session文件是不會刪除的。雖然關閉瀏覽器,

下次需要重新分配一個新的Session ID重新登錄,但這只是因為在php.ini中的設置seesion.cookie_lifetime=0,來設定Session ID在客户端Cookie中的有效限期,以秒為單位指定了發送到瀏覽器的Cookie的生命週期。當系統賦予Session有效期限後不管瀏覽器是否開啟,Session ID都會自動消失。而客户端Session ID消失服務器端保存的Session文件並沒有被刪除。所以沒有被Sessoin ID引用的服務器端Session文件,就成為了“垃圾”。

服務器保存的Session文件就是一個普通文本文件,所以都會有文件修改時間。“垃圾回收程序”啟動後就是根據Session文件的修改時間,將所有過期的Session文件全部刪除。通過在php.ini中設置session.gc_maxlifetime選項來指定一個時間(單位:秒),例如設置該選項值為1440(24分鐘)。“垃圾回收程序”就會在所有Session文件中排查,如果有修改時間距離當前系統時間大於1440秒的就將其刪除。

“session垃圾回收程序”是怎樣的啟動機制呢?“垃圾回收程序”是在調用session_start()函數時啟動的。而一個網站有多個腳本,沒有腳本又都要使用session_start()函數開啟會話,又會有很多個用户同時訪問,這就很可能session_start()函數在1秒內被調用N次,而如果每次都會啟動“session垃圾回收程序”,這樣是很不合理的。

可以通過php.ini文件中修改“session.gc_probability和session.gc_divisor”兩個選項,設置啟動垃圾回收程序的概率。會根據“session.gc_probability/session.gc_divisor”公示計算概率,例如選項session.gc_probability=1,而選項session.gc_divisor=100,這樣的概率就是“1/100”,即session_start()函數被調用100次才會有一次可能啟動“垃圾回收程序”。

 

php.ini中相關的配置

session.cookie_lifetime=0; 關閉瀏覽器相應的cookie文件即被刪除
session.gc_maxlifetime; 設置過期session時間,默認1440秒(24分鐘)
session.gc_probability/session.gc_divisor; 啟動垃圾回收機制的概率(建議值為1/1000——5000)

cookie禁用時通過URL傳遞session的ID

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

  第一種方法是基於cookie的方式傳遞session ID,這種方式更優,但不總是可用, 因為用户在客户端可以屏蔽cokie;

  第二種方法是通過url參數進行傳遞,直接將session ID嵌入到URL中去。

在Session的實現中通常都是採用Cookie的方式,客户端保存的Session ID就是一個Cookie。當客户禁用Cookie時,Session ID就不能在Cookie中保存,也就不能在頁面之間傳遞,此時Session失效。不過PHP5在Linux平台可以自動檢查Cookie狀態,如果客户端禁用它,則系統自動把Session ID附加到URL上傳送。而使用Windows系統作為Web服務器則無此功能。

  在PHP中提出了跟蹤Session的另一種機制,如果客户瀏覽器不支持Cookie,則PHP可以重寫客户請求的URL,把Session ID添加到URL信息中。可以手動地在每個超鏈接的URL中都加上一個Session ID,但工作量比較大,不建議使用這種方法。如下所示:

<?php
//開啟session
session_start();

//在每個URL後面附加上參數,變量名為session_name()獲取名稱,值通過session_id()獲取
echo '<a href="demo.php?'.session_name().'='.session_id().'">連接演示</a>';
?>
在使用Linux系統做服務器時,則在編輯PHP時如果使用了–enable-trans-sid配置選項,和運行時選項session.use_trans_sid都被激活,在客户端禁用Cookie時,相對URL將被自動修改為包含會話ID。如果沒有這麼配置,或者使用Windows系統作為服務器時,可以使用常量SID。該常量在會話啟動時被定義,如果客户端沒有發送適當的會話Cookie,則SID的格式為session_name=session_id,否則就為一個空字符串。因此可以無條件地將其嵌入到URL中去。在下例中使用兩個腳本程序,演示了Session ID的傳送方法。
<?php
session_start();

$_SESSION["username"]="admin";

echo "session ID:".session_id()."<br>";

?>

以上內容希望幫助到大家,很多PHPer在進階的時候總會遇到一些問題和瓶頸,業務代碼寫多了沒有方向感,更多PHP大廠PDF面試文檔,PHP進階架構視頻資料,PHP精彩好文免費獲取可以關注公眾號:PHP開源社區,或者訪問:

2021金三銀四大廠面試真題集錦,必看!

四年精華PHP技術文章整理合集——PHP框架篇

四年精華PHP技術文合集——微服務架構篇

四年精華PHP技術文合集——分佈式架構篇

四年精華PHP技術文合集——高併發場景篇

四年精華PHP技術文章整理合集——數據庫篇