php session回收機制
由於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:WindowsTemp。當伺服器上有多個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。
php session GC功能,就是Garbage Collector。這個GC啟動的時候,會清除那些已經「逾時」的session。它的工作原理是這樣的:
用戶訪問並登陸網站,這時候後台會調用session_start來嘗試產生一個會話(如果已經有會話,則相當於一次有效會話請求)
對於這樣的每一次有效會話請求(Request),apache的php模組會根據session相關的全域變數gc_probability/gc_divisor =>計算啟動GC的機率,並由此機率來決定在這次請求中是否應該啟動GC。舉例來說,session.gc_probability的缺省值為1,session.gc_divisor的缺省值為100,則啟動「垃圾回收」器的機率是1%,這就意味著在每100次請求中,會有可能清理一次過期會話
如果GC啟動,則GC會掃描當前會話所在路徑(session.save_path)下的所有會話文件,並根據另外一個全域變數session.gc_maxlifetime的多少來判斷哪些session已經過期(「目前時間」與「會話檔案的atime或mtime」之間的差大於gc_maxlifetime:過期),並刪除這些過期的session
如果你在一個session啟動後,長時間沒有任何交互操作(譬如,不停地碼字,沒有提交或保存為草稿),那麼你的保存在後台的會話文件將得不到機會被修改或者訪問,在gc_maxlifetime(缺省值1440秒=24分鐘)時間後,它有可能因失效而被清理,這以後你再提交,就會因為會話失效而報錯
由此可見,gc_maxlifetime設定為24分鐘,對於寫某些文章來說還不夠。這是一個原因,另外,session.save_path的預設路徑在linux上是/tmp,很少程式會修改這個設定。如果這台伺服器上有多個虛擬主機,那麼,/tmp目錄下會存放許多不同session_name的會話檔案。糟糕的是,php的GC不區分會話歸屬,它會根據它取得的gc_maxlifetime來清理這個目錄下的所有過期session檔案。
據以上分析,解決方案是:UTBLOG在.htaccess檔案內加入了一條語句,將session.gc_maxlifetime的local value擴大為14400(4小時),同時在後台將session.save_path設定為/tmp/utblog,這樣,utblog的會話文件就不受其他網站幹擾了,而4小時的失效時間,我想,無論如何應該夠用了。
測試下來,一切如我所願。
另,如果直接改動/etc/php.ini當然也可以。如果沒有權限改動php.ini,也沒有權限改動apache的conf文件,.htaccess被禁止,那麼直接修改plog的sessionmanager.class.php文件,在session_start行前添加ini_alter("session.gc_maxlifetime", 14400)亦可。 plog結構良好,只有這一處呼叫session_start,所以也只有這一處需要修改。我在本地做過測試,可以工作。
------------------------------------------------ --------------------------
session.gc_probability integer
session.gc_probability 與 session.gc_divisor 合起來用來管理gc(garbage collection垃圾回收)進程啟動的機率。預設為 1。詳見 session.gc_divisor。
session.gc_divisor integer
session.gc_divisor 與 session.gc_probability 合起來定義了在每個會話初始化時啟動 gc(garbage collection 垃圾回收)進程的機率。此機率用 gc_probability/gc_divisor 計算得來。例如 1/100 意味著在每個請求中有 1% 的機率啟動 gc 進程。 session.gc_divisor 預設為 100。
session.gc_maxlifetime integer
session.gc_maxlifetime 指定過了多少秒之後資料就會被視為「垃圾」並被清除。
Note:
如果不同的腳本具有不同的 session.gc_maxlifetime 數值但是共享了同一個地方存儲會話數據,則具有最小數值的腳本會清理數據。此情況下,與 session.save_path 一起使用本指令。
Note: 如果使用預設的基於檔案的會話處理器,則檔案系統必須保持追蹤存取時間(atime)。 Windows FAT 檔案系統不行,因此如果必須使用 FAT 檔案系統或其他無法追蹤 atime 的檔案系統,那就不得不想別的辦法來處理會話資料的垃圾回收。自 PHP 4.2.3 起用 mtime(修改時間)來取代了 atime。因此對於無法追蹤 atime 的檔案系統也沒問題了。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

PHP 8.4 帶來了多項新功能、安全性改進和效能改進,同時棄用和刪除了大量功能。 本指南介紹如何在 Ubuntu、Debian 或其衍生版本上安裝 PHP 8.4 或升級到 PHP 8.4

CakePHP 是 PHP 的開源框架。它旨在使應用程式的開發、部署和維護變得更加容易。 CakePHP 基於類似 MVC 的架構,功能強大且易於掌握。模型、視圖和控制器 gu

Visual Studio Code,也稱為 VS Code,是一個免費的原始碼編輯器 - 或整合開發環境 (IDE) - 可用於所有主要作業系統。 VS Code 擁有大量針對多種程式語言的擴展,可以輕鬆編寫

CakePHP 是一個開源MVC 框架。它使應用程式的開發、部署和維護變得更加容易。 CakePHP 有許多函式庫可以減少大多數常見任務的過載。

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲
