因爲PHP的工做機制,它並無一個daemon線程,來定時地掃描session信息並判斷其是否失效。當一個有效請求發生時,PHP會根據全局變量 session.gc_probability/session.gc_divisor(一樣能夠經過php.ini或者ini_set()函數來修改) 的值,來決定是否啓動一個GC(Garbage Collector)。默認狀況下,session.gc_probability = 1,session.gc_divisor =100,也就是說有1%的可能性會啓動GC。
GC的工做,就是掃描全部的session信息, 用當前時間減去session的最後修改時間(modified date),同session.gc_maxlifetime參數進行比較,若是生存時間已經超過gc_maxlifetime,就把該session刪 除。
那爲何會發生gc_maxlifetime無效的狀況呢?
在默認狀況下,session信息會以文本文件的形式,被保存在系統 的臨時文件目錄中。在Linux下,這一路徑一般爲\tmp,在Windows下一般爲C:\Windows\Temp。當服務器上有多個PHP應用時, 它們會把本身的session文件都保存在同一個目錄中。一樣地,這些PHP應用也會按必定機率啓動GC,掃描全部的session文件。
問 題在於,GC在工做時,並不會區分不一樣站點的session。舉例言之,站點A的gc_maxlifetime設置爲2小時,站點B的 gc_maxlifetime設置爲默認的24分鐘。當站點B的GC啓動時,它會掃描公用的臨時文件目錄,把全部超過24分鐘的session文件所有刪 除掉,而無論它們來自於站點A或B。這樣,站點A的gc_maxlifetime設置就形同虛設了。
找到問題所在,解決起來就很簡單了。修改session.save_path參數,或者使用session_save_path()函數,把保存session的目錄指向一個專用的目錄,gc_maxlifetime參數工做正常了。
還有一個問題就是,gc_maxlifetime只能保證session生存的最短期,並不可以保存在超過這一時間以後session信息當即 會獲得 刪除。由於GC是按機率啓動的,可能在某一個長時間內都沒有被啓動,那麼大量的session在超過gc_maxlifetime之後仍然會有效。解決這 個問題的一個方法是,把session.gc_probability/session.gc_divisor的機率提升,若是提到100%,就會完全解 決這個問題,但顯然會對性能形成嚴重的影響。另外一個方法是本身在代碼中判斷當前session的生存時間,若是超出了gc_maxlifetime,就清 空當前session。
Tiwer
在window下設置wamp的session時間,即便設置了10秒超時,到時間都不會清空session。
linux的設置:
在apache1.2以上的版本中,能夠在httpd.conf裏面設置:
KeepAlive on
KeepAliveTimeout 15
session.auto_start 開啓就自動完成了session_start()
php.ini 中 session.auto_start 開啓與關閉的區別
區別就在於在用SESSION前是否須要session_start();
當session.auto_start = on
時,執行 session_start() 將產生新的 session_id
session.auto_start = on 的優勢在於,任什麼時候候都不會因忘記執行 session_start() 或 session_start() 在程序裏的位置不對,而致使錯誤
缺點在於,若是你使用的是第三方代碼,則必須刪去其中的所有 session_start() 。不然將不能獲得正確的結果php