php中Session的生成機(jī)制、回收機(jī)制和存儲機(jī)制探究
1、php中session的生成機(jī)制
我們先來分析一下PHP中是怎么生成一個session的。設(shè)計出session的目的是保持每一個用戶的各種狀態(tài)來彌補HTTP協(xié)議的不足(無狀態(tài))。我們現(xiàn)在有一個疑問,我們都知道session是保存在服務(wù)器的,既然它用于保持每一個用戶的狀態(tài)那它利用什么來區(qū)別用戶的呢?這個時候就得借助cookie了。當(dāng)我們在代碼中調(diào)用session_start();時,PHP會同時往SESSION的存放目錄(默認(rèn)為/tmp/)和客戶端的cookie目錄各生成一個文件。session文件名稱像這樣:
格式為sess_{SESSIONID} ,這時session文件中沒有任何內(nèi)容,當(dāng)我們在session_start();添加了這兩行代碼:
$_SESSION['name'] = 'wanchun0222';
$_SESSION['blog'] = 'coderbolg.net';
這時文件就有內(nèi)容了:
name|s:11:"wanchun0222";blog|s:13:"coderbolg.net";
這時再看看cookie:
可以看到服務(wù)器為我們自動生成了一個cookie,cookie名稱為"PHPSESSID",cookie內(nèi)容是一串字符,其實這串字符就是{SESSIONID}。也許你已經(jīng)明白了,當(dāng)我們使用session時,PHP就先生成一個唯一的SESSIONID號(如2bd170b3f86523f1b1b60b55ffde0f66),再在我們服務(wù)器的默認(rèn)目錄下生成一個文件,文件名為sess_{SESSIONID},同時在當(dāng)前用戶的客戶端生成一個cookie,內(nèi)容已經(jīng)說過了。這樣PHP會為每一個用戶生成一個SESSIONID,也就是說一個用戶一個session文件。PHP第一次為某個用戶使用session時就向客戶端寫入了cookie,當(dāng)這個用戶以后訪問時,瀏覽器會帶上這個cookie,PHP在拿到cookie后就讀出里面的SESSIONID,拿著這個SESSIONID去session目錄下找session文件。找到后在調(diào)用$_SESSION['blog']的時候顯示出來。
2、php中session的過期回收機(jī)制
我們明白了session的生成及工作原理,發(fā)現(xiàn)在session目錄下會有許多session文件。當(dāng)然這些文件一定不是永遠(yuǎn)存在的,PHP一定提供了一種過期回收機(jī)制。在php.ini中session.gc_maxlifetime為session設(shè)置了生存時間(默認(rèn)為1440s)。如果session文件的最后更新時間到現(xiàn)在超過了生存時間,這個session文件就被認(rèn)為是過期的了。在下一次session回收的時候就會被刪除。那下一次session回收是在什么時候呢?這和php請求次數(shù)有關(guān)的。在PHP內(nèi)部機(jī)制中,當(dāng)php被請求了N次后就會有一次觸發(fā)回收機(jī)制。到底是請求多少次觸發(fā)一次是通過以下兩個參數(shù)控制的:
session.gc_probability = 1
session.gc_divisor = 100
這是php.ini的默認(rèn)設(shè)置,意思是每100次PHP請求就有一次回收發(fā)生。概率是 gc_probability/gc_divisor 。我們了解了服務(wù)器端的session過期機(jī)制,再來看看客戶端的cookie的過期機(jī)制。
如果cookie失效了瀏覽器自然發(fā)送不了cookie到服務(wù)器,這時即使服務(wù)器的session文件存在也沒用,因為PHP不知道要讀取哪個session文件。我們知道PHP的cookie過期時間是在創(chuàng)建時設(shè)置的,那么PHP在創(chuàng)建session的同時為客戶端創(chuàng)建的cookie的生命周期是多久呢?這個在php.ini中有設(shè)置:session.cookie_lifetime 。這個值默認(rèn)是0,代表瀏覽器一關(guān)閉SESSIONID就失效。那就是說我們把session.gc_maxlifetime和session.cookie_lifetime設(shè)置成同一個值就可以控制session的失效時間了。
3、php中session的客戶端存儲機(jī)制
由上面的介紹我們可以知道,如果用戶關(guān)閉了cookie,那我們的session就完全沒法工作了。是的,確實是這樣。php中session的客戶端存儲機(jī)制只有cookie嗎?不是的。既然我們的SESSIONID 不能通過cookie傳遞到各個頁面,那我們還有另一個法寶,就是通過頁面GET傳值的方式。
PHP可以在cookie被禁用時自動通過GET方式跨頁傳遞SESSIONID,前提是設(shè)置php.ini的session.use_trans_sid為1。這時當(dāng)我們在客戶端禁用了cookie時使用了session,并在當(dāng)前頁面通過點擊鏈接到另一頁面時,PHP會自動在鏈接上添加SESSIONID參數(shù),像這樣:nextpage.php?SESSIONID=2bd170b3f86523f1b1b60b55ffde0f66。我想你應(yīng)該看到了這種方式的缺點:好像不夠安全啊。
相關(guān)文章
PHP使用PHPExcel實現(xiàn)批量上傳到數(shù)據(jù)庫的方法
下面小編就為大家?guī)硪黄狿HP使用PHPExcel實現(xiàn)批量上傳到數(shù)據(jù)庫的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-06-06講解WordPress開發(fā)中一些常用的debug技巧
這篇文章主要介紹了WordPress開發(fā)中一些常用的debug技巧,需要的朋友可以參考下2015-12-12PHP基于ffmpeg實現(xiàn)轉(zhuǎn)換視頻,截圖及生成縮略圖的方法
這篇文章主要介紹了PHP基于ffmpeg實現(xiàn)轉(zhuǎn)換視頻,截圖及生成縮略圖的方法,涉及php使用ffmpeg針對視頻文件的截圖、生成縮略圖等相關(guān)操作技巧,需要的朋友可以參考下2017-08-08php swoole多進(jìn)程/多線程用法示例【基于php7nts版】
這篇文章主要介紹了php swoole多進(jìn)程/多線程用法,結(jié)合實例形式分析了基于php7nts版使用swoole進(jìn)行多線程創(chuàng)建、調(diào)用相關(guān)操作技巧,需要的朋友可以參考下2019-08-08解析php函數(shù)method_exists()與is_callable()的區(qū)別
本篇文章是對php中method_exists()與is_callable()的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06