今天复习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或者数据库会和文件存储形式一样么。