今天複習session,有了更進一步的理解,同時也有幾個疑惑,請大家幫忙分析一下哈。
第一個問題,在php裡,session是有垃圾回收機制的,原理是觸發多少次session_start
就可能觸發垃圾回收機制。那麼我的問題是,如果我的session已經過了1440秒,但是此時沒有立即觸發回收,可能5分鐘內也沒觸發,此時我還能獲取到session的數據麼?
第二個問題,關於session的過期原理,書本上說的都說是按照session文件的修改時間。我的問題如下:1)我一般造訪一個網站,在沒有修改session資料的情況下,是不是在1440秒後準確退出。 2)還是說我每刷新一次網頁,session檔都會修改filemtime
呢? session的執行原理是怎樣的。
第三個問題,就是php的session_set_save_handler
設定問題了,只有知道了session是怎麼處理filemtime
的,才能寫好session_set_save_handler
中的read修改
filemtime的話,勢必要在
read中修改
filemtime吧。
阿神2017-05-16 13:04:04
原則上你是獲得不到的,因為獲得的程式碼是透過 PHP 讀出來的,而讀的過程還會再一次檢測是否過期,過期的話依舊是無法取得。
1) 以 php.ini 中的配置時間準確非失效,預設是 1440 。你可以程式中修改這個設置,但還是建議修改設定檔。為什麼說是非準確失效呢?是因為PHP 非常駐內存,因此需要藉助每次請求來確認某些定時任務是否觸發,這是其一,其次就是為了減小每次垃圾回收帶來的性能損耗, PHP 設定了兩個參數來控制垃圾回收的機率,分別是session.gc_probability 和session.gc_pisor ,gc_probability/gc_pisor 是機率,如1/100 的話,那麼至少有100次請求才觸發一次。
2) 每刷新一次, filetime 都會變更。
查看了 Laravel 框架的 session 實現,以下分別是文件存儲和資料庫存儲形式:
public function read($sessionId)
{
if ($this->files->exists($path = $this->path.'/'.$sessionId)) {
if (filemtime($path) >= Carbon::now()->subMinutes($this->minutes)->getTimestamp()) {
return $this->files->get($path);
}
}
return '';
}
public function read($sessionId)
{
$session = (object) $this->getQuery()->find($sessionId);
if (isset($session->last_activity)) {
if ($session->last_activity < Carbon::now()->subMinutes($this->minutes)->getTimestamp()) {
$this->exists = true;
return;
}
}
if (isset($session->payload)) {
$this->exists = true;
return base64_decode($session->payload);
}
}
沒有查到類似刷新 filetime 的相關程式碼。
仅有的幸福2017-05-16 13:04:04
經過試驗,在檔案儲存的情況下,設定session.gc_maxlifetime為30秒,在超過30秒的情況下,仍然可以出去session資料。並且在下次刷新的情況下,filemtime確實會改成當前。
誰能來解釋一下為什麼,並且把自訂儲存改為memcache或資料庫會和檔案儲存形式一樣麼。