https://segmentfault.com/q/1010000000191102
首先 ...?session_destory()?是一個函數 ...
這個函數在任何情況下都不會被 php 引擎自動調用 ... 只能你手工去調用 ...
php 內部存在著清理 session 的機制 ... 但與這個函數完全無關 ...
如果你想問的是什么時候該手工調用這個函數 ...答案就是在你想完全清理掉當前 session 的時候 ...
問題里面提及的幾種情況 ... 不管是關閉網頁也好 ... 關閉瀏覽器也罷 ... 甚至你把瀏覽器刪掉重裝了 ...
都不會影響到已經生成的 session ... 一言以蔽之 ... 所有瀏覽器行為都不會導致 session 被自動銷毀 ...
那么 ... php 到底是如何清理 session 的呢 ..?
仔細去讀?php.ini?... 你可以發現如下幾行 ...
; Defines the probability that the 'garbage collection' process is started
; on every session initialization. The probability is calculated by using ; gc_probability/gc_divisor. Where session.gc_probability is the numerator ; and gc_divisor is the denominator in the equation. Setting this value to 1 ; when the session.gc_divisor value is 100 will give you approximately a 1% ; chance the gc will run on any give request. ; Default Value: 1 ; Development Value: 1 ; Production Value: 1 ; http://php.net/session.gc-probability session.gc_probability = 1 ; Defines the probability that the 'garbage collection' process is started ; on every session initialization. The probability is calculated by using ; the following equation: gc_probability/gc_divisor. Where session.gc_probability ; is the numerator and session.gc_divisor is the denominator in the equation. ; Setting this value to 1 when the session.gc_divisor value is 100 will give you ; approximately a 1% chance the gc will run on any give request. Increasing this ; value to 1000 will give you a 0.1% chance the gc will run on any give request. ; For high volume production servers, this is a more efficient approach. ; Default Value: 100 ; Development Value: 1000 ; Production Value: 1000 ; http://php.net/session.gc-divisor session.gc_divisor = 1000 ; After this number of seconds, stored data will be seen as 'garbage' and ; cleaned up by the garbage collection process. ; http://php.net/session.gc-maxlifetime session.gc_maxlifetime = 1440
其實英文的注釋已經說得很明白了 ... 但如果你不想看 ... 我也可以解釋給你聽 ...
由于 php 的工作機制 ... 它本身不會提供 daemon 來定時掃描 session 信息并判斷其是否失效 ...
當你每次調用?session_start()?時 ...
php 會根據?session.gc_probability
?和?session.gc_divisor
?來決定是否啟用 Garbage Collector ...
Garbage Collector 顧名思義 ... 被叫做?垃圾回收器
?... 也就是俗稱的 GC ...
具體一些講 ... 在我剛剛貼的配置文件里 ...
session.gc_probability = 1
session.gc_divisor = 1000
就是說 php 會有千分之一的概率會啟動垃圾回收 ...
而垃圾回收的工作就是在 session 存儲路徑?session.save_path
?下掃描所有存在的 session ...
然后用當前時間減去每個 session 的最后修改時間再跟?session.gc_maxlifetime
?參數進行比較 ...
如果某個 session 的生存時間超過了?session.gc_maxlifetime
?的設定值就把它銷毀掉 ...
事實上這個過程完全是 php 引擎的行為 ... 和你的程序無關 ... 和用戶做了什么也無關 ...
用戶關閉瀏覽器再開 ... 因為 cookie 失效他會獲得一個新的 session ...
但這并不代表他原來的 session 就被銷毀了 ... 那個 session 依然在服務器上存在 ...
如果他手動把名字等于?session.name
?的那個 cookie 的值改回之前的?session_id()?...
還是可以重新獲得之前的那個 session 的 ...
另外一種情況 ... 如果一個用戶獲得 session 之后長時間沒有任何動作 ...
他就可能因為其他用戶觸發了垃圾回收而丟失掉自己的 session ...
大體來說就是如此 ... 更加細節的東西 ... 你可以參考 php 手冊上?關于垃圾回收的章節?...
恩 ... 就是這樣啦 ...
//-------------------------------------------------------------------------------
深入理解session過期機制
首先得明白:session的過期時間由兩方面決定的;?
1存儲在客戶端的$_COOKIE['PHPSESSID']的過期時間(默認cookie名稱為PHPSESSID,可通過php.ini中的session.name修改。)?
2.存儲在服務器端的相對應的session文件(session文件名和上述cookie的值一一對應),默認為1440秒,即24分鐘?
ok,現在詳細闡述上述兩者的關系:?當執行session_start()的時候,其實是做了兩件事:?1,檢查客戶端發送過來的的所有cookie(當然也包括$_COOKIE['PHPSESSID'],?如果有的話),根據$_COOKIE['PHPSESSID']的值(這是由apache產生的隨機字符串,如0lkbd2se458r600m2m7o1r4ic5)來訪問?相對應的 session文件(如:sess_0lkbd2se458r600m2m7o1r4ic5,我的默認存儲在‘E:\wamp\tmp’下),這兩者是一 一對應的關系。打個比喻:$_COOKIE['PHPSESSID']就是一把開啟寶盒的鑰匙,而那個寶盒就是session文件,里面存儲著用戶的重要 信息,也就是session的值, 如:$_SESSION['uid']=1,$_SESSION['username']='name',$_SESSION['pwd']='pwd', 當然文件里面的值是經過序列化的。?2,如果客戶端沒有傳來$_COOKIE['PHPSESSID'],就會有服務端產生一個隨機的$_COOKIE['PHPSESSID']并存儲在客戶端。?
明白上面這些,我們可以通過下面的方法修改session的過期時間:?
1.session_set_cookie_params('50');//修改$_COOKIE['PHPSESSID'],的生存時間為50秒?
(或者可以這樣:?setcookie(session_name(),session_id(),time()+50);)?
2.ini_set('session.gc_maxlifetime','50');//設置session文件的有效時間為50秒?
但是,可能有些朋友會做這樣?一個試驗, 在50秒內獲取$_COOKIE['PHPSESSID']的值并記錄下來(如黑客截獲這個cookie),這樣等50秒過后發現原先 的$_COOKIE['PHPSESSID']值確實不存在了,而出現了一個新的$_COOKIE['PHPSESSID'],但是‘E:\wamp \tmp’下的舊session文件卻沒有消失(默認只有1/1000的概率會消失,應該不會碰到吧,呵呵),這是為什么呢?我不是已經設置了.ini_set('session.gc_maxlifetime','50');了 嗎?再做一個實驗:這時你偽造一個$_COOKIE['PHPSESSID'],值為剛才你記錄下的,神奇的事發生了,你依然可以訪問剛才舊的 session文件!!!(雖然他已經過期),只要這個文件沒被刪除,用相對應得$_COOKIE['PHPSESSID']依然可以進行訪問!!!?
那我們設置ini_set('session.gc_maxlifetime', '50');還有什么意義呢?這就涉及的GC(GarbageCollector)的回收機制。?
默 認情況下,session.gc_probability = 1,session.gc_divisor=1000,也就是說有1/1000的可能性會啟動GC。GC的工作,就是掃描所有的session信息,用當 前時間減去session的最后修改時間(modifieddate),同session.gc_maxlifetime參數進行比較,如果生存時間已經 超過gc_maxlifetime,就把該session刪除。只要沒有啟動GC,即使session過期,也仍舊可通過相對應 得$_COOKIE['PHPSESSID']進行訪問!?
???
原文參考:?http://www.jb51.net/article/26890.htm?
?????????????????http://www.php100.com/html/webkaifa/PHP/PHPyingyong/2012/0621/10583.html