今天復(fù)習(xí)session,有了更進(jìn)一步的理解,同時(shí)也有幾個(gè)疑惑,請(qǐng)大家?guī)兔Ψ治鲆幌鹿?/p>
第一個(gè)問(wèn)題,在php里,session是有垃圾回收機(jī)制的,原理是觸發(fā)多少次session_start
就可能觸發(fā)垃圾回收機(jī)制。那么我的問(wèn)題是,如果我的session已經(jīng)過(guò)了1440秒,但是此時(shí)沒(méi)有立即觸發(fā)回收,可能5分鐘內(nèi)也沒(méi)觸發(fā),此時(shí)我還能獲取到session的數(shù)據(jù)么?
第二個(gè)問(wèn)題,關(guān)于session的過(guò)期原理,書(shū)本上說(shuō)的都說(shuō)是按照session文件的修改時(shí)間。我的疑問(wèn)如下:1)我普通訪問(wèn)一個(gè)網(wǎng)站,在沒(méi)有修改session數(shù)據(jù)的情況下,是不是在1440秒后準(zhǔn)確退出。2)還是說(shuō)我每刷新一次網(wǎng)頁(yè),session文件都會(huì)修改filemtime
呢?session的執(zhí)行原理是怎樣的。
第三個(gè)問(wèn)題,就是php的session_set_save_handler
設(shè)置問(wèn)題了,只有知道了session是怎么處理filemtime
的,才能寫(xiě)好session_set_save_handler
中的read
方法,因?yàn)槿绻敲克⑿乱淮尉W(wǎng)頁(yè)就算修改filemtime
的話,勢(shì)必要在read
中修改filemtime
吧。
原則上你是獲得不到的,因?yàn)楂@得的代碼是通過(guò) PHP 讀出來(lái)的,而讀的過(guò)程還會(huì)再一次檢測(cè)是否過(guò)期,過(guò)期的話依舊是無(wú)法獲得。
1) 按著 php.ini 中的配置時(shí)間準(zhǔn)確非失效,默認(rèn)是 1440 。你可以程序中修改這個(gè)設(shè)置,但是還是建議修改配置文件。為什么說(shuō)是非準(zhǔn)確失效呢?是因?yàn)?PHP 非常駐內(nèi)存,因此需要借助每次請(qǐng)求來(lái)確認(rèn)某些定時(shí)任務(wù)是否觸發(fā),這是其一,其次就是為了減小每次垃圾回收帶來(lái)的性能損耗, PHP 設(shè)置了兩個(gè)參數(shù)來(lái)控制垃圾回收的概率,分別是 session.gc_probability 和 session.gc_pisor ,gc_probability/gc_pisor 就是概率,如1/100 的話,那么至少是有100次請(qǐng)求才觸發(fā)一次。
2) 每刷新一次, filetime 都會(huì)變化。
查看了 Laravel 框架的 session 實(shí)現(xiàn),以下分別是文件存儲(chǔ)和數(shù)據(jù)庫(kù)存儲(chǔ)形式:
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);
}
}
沒(méi)有查到類似刷新 filetime 的相關(guān)代碼。
經(jīng)過(guò)試驗(yàn),在文件存儲(chǔ)的情況下,設(shè)置session.gc_maxlifetime為30秒,在超過(guò)30秒的情況下,仍然可以出去session數(shù)據(jù)。并且在下次刷新的情況下,filemtime確實(shí)會(huì)改成當(dāng)前。
誰(shuí)能來(lái)解釋一下為什么,并且把自定義儲(chǔ)存改為memcache或者數(shù)據(jù)庫(kù)會(huì)和文件存儲(chǔ)形式一樣么。