昨天下午纠结,想做一个10秒就自动清除的会话。
虽然后来采用了session+timestamp的方法,但是gc的回收机制却困扰了我。
根据说明,session的gc是根据以下三个参数。
session_start()是session机制的开始,它有一定概率开启垃圾回收
'session.gc_maxlifetime:'. ini_get('session.gc_maxlifetime')."<br/>";
'session.gc_probability:'. ini_get('session.gc_probability')."<br/>";
'session.gc_divisor:'. ini_get('session.gc_divisor')."<br/>";
于是我把maxlifetime设置为10,probability 和divisor同时设置为1.
天真的以为10秒后会自动删除。
(注:win下phpstudy环境)
首先自定义关于php session的三个简单文件
read.php 读
write 写
gc 回收
1、写入session
<?php
session_start();
$_SESSION['nowtime']=date('Y-m-d H:i:s',time());
echo 'session.gc_maxlifetime:'. ini_get('session.gc_maxlifetime')."<br/>";
echo 'session.gc_probability:'. ini_get('session.gc_probability')."<br/>";
echo 'session.gc_divisor:'. ini_get('session.gc_divisor')."<br/>";
echo 'session-id:'.session_id()."<br/>";
echo 'session-name:'.session_name()."<br/>";
echo '<hr>';
echo 'write success in '.date('Y-m-d H:i:s',time());
session_write_close();
2、读取session和cookie
<?php
session_start();
echo 'session.gc_maxlifetime:'. ini_get('session.gc_maxlifetime')."<br/>";
echo 'session.gc_probability:'. ini_get('session.gc_probability')."<br/>";
echo 'session.gc_divisor:'. ini_get('session.gc_divisor')."<br/>";
echo '<hr>'.'Session::=>';
var_dump($_SESSION);
echo '<hr>'.'Cookie::=>';
var_dump($_COOKIE);
echo '<hr>';
echo "<br>ReadTime".date('Y-m-d H:i:s',time());
3、触发session_start ,(按照官方说必须触发start才能开始gc回收)
<?PHP
session_start();
session_write_close();
echo 'session_start execute ';
var_dump($_SESSION);
那么问题来了,用浏览器1一次访问 write,read,gc,然后10秒中之后,再次访问read。那个sessionid还是在那里一动不动。
后来换了本机其他浏览器(浏览器2),原来的sessionid就被清除掉了
。但是有个问题,即使我把回收站直接删除,在用浏览器1访问,sessionid的名字仍然是删除的那个。不知道他把这个sessionid到底存放在哪里。这些貌似不是大问题,因为一般网站触发其他的请求后,那么gc回收就起效了。
但是这种放在文件中存储session,如果遇到百万或者千万访问,gc要开启100%,他会依次比较当前时间减去mtime的差额,然后与maxlifetime设置的时间做对比。这样内存开销还是很大的。
so,那我们只能借助session_set_save_handler() 函数来设置自定义会话保存管理器。
大概流程是这样:
open:会话开始,调用open管理器
read:读取已经编码过的字符串
write:解码字符串,产生数组对象,放在$_SESSION全局数组变量,然后将session_id 一 起返回,调用close。
destory:会话结束时调用
此外,PHP 会不时地调用 gc 回调函数。 该函数会从持久化存储中删除超时的会话数据。
就是设置的maxlifetime值。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。