我需要让一个会话保持活动状态30分钟,然后销毁它
您应该实现自己的会话超时。其他人提到的两个选项(session.gc_maxlife和session.cookie_life)都不可靠。我会解释原因的
第一名:
session.gc\u maxlifetime
session.gc_maxlife指定数据被视为“垃圾”并被清除的秒数。垃圾回收在会话启动期间发生
但是垃圾收集器的启动概率只有session.gc\u概率除以session.gc\u除数。使用这些选项的默认值(分别为1和100),概率仅为1%
您可以简单地调整这些值,以便更频繁地启动垃圾收集器。但是当垃圾收集器启动时,它将检查每个注册会话的有效性。这是成本密集型的
此外,当使用PHP的默认session.save_handler文件时,会话数据存储在文件中,路径在session.save_path中指定。使用该会话处理程序,会话数据的期限是根据文件的最后修改日期而不是最后访问日期计算的:
注意:如果使用默认的基于文件的会话处理程序,则文件系统必须跟踪访问时间(atime)。Windows FAT不是这样的,因此如果您使用的是FAT文件系统或任何其他无法使用atime跟踪的文件系统,那么您必须想出另一种方法来处理会话垃圾收集。自PHP4.2.3以来,它使用了mtime(修改日期)而不是atime。这样,您就不会在没有atime跟踪的文件系统中遇到问题
因此,由于会话数据最近未更新,因此在会话本身仍被视为有效时,会话数据文件可能会被删除
第二名:
会话。cookie\u生存期
session.cookie_lifetime指定发送到浏览器的cookie的生存期(以秒为单位)。[……]
是的,没错。这只会影响cookie生存期,会话本身可能仍然有效。但是,使会话无效是服务器的任务,而不是客户端的任务。所以这没有任何帮助。事实上,将会话.cookie\u life设置为0将使会话的cookie成为真正的会话cookie,只有在浏览器关闭时才有效
结论/最佳解决方案:
最好的解决方案是实现自己的会话超时。使用简单的时间戳表示最后一个活动(即请求)的时间,并随每个请求更新:
if(isset($\u会话['LAST\u活动])&;(time()-$\u会话['LAST\u活动]]>;1800)){
//上次请求是在30多分钟前
session_unset();//运行时的unset$_会话变量
会话_destroy();//销毁存储中的会话数据
}
$\u会话['LAST\u ACTIVITY']=time();//更新上次活动时间戳
使用每个请求更新会话数据也会更改会话文件的修改日期,以便垃圾收集器不会过早删除会话
您还可以使用额外的时间戳定期重新生成会话ID,以避免对会话的攻击,如会话固定:
if(!isset($\u会话['CREATED'])){
$\u会话['CREATED']=time();
}else if(time()-$\u会话['CREATED']>;1800){
//会议在30分钟前开始
session_regenate_id(true);//更改当前会话的会话id并使旧会话id无效
$\u会话['CREATED']=time();//更新创建时间
}
注意事项:
session.gc_maxlifetime应至少等于此自定义过期处理程序的生存期(本例中为1800)- 如果您想在活动的30分钟后使会话过期,而不是在启动后的30分钟后,您还需要使用
setcookie,过期时间为time()+60*30,以保持会话cookie处于活动状态