有关PHP中会话过期的问题。
如果该用户暂时处于非活动状态(出于测试目的,为5秒),我需要我的服务器丢弃会话信息。
我看过this question,特别是Gumbo的答案(+28票),我一直在想这个答案对于非活跃用户的可行性。在我的网站上,我已经实现了这个建议并且它工作正常,只要用户在会话过期后至少请求一次数据。但非活动用户的问题是他们不会请求新数据。因此永远不会调用到期代码。
我一直在查看我的PHP.ini中的session.gc_maxlife
及相关参数,但我无法按照我想要的方式进行此操作。
有关此问题的任何建议吗?
答案 0 :(得分:3)
session expiration logic I mentioned已经做了您所期望的事情:会话一旦过期就无法使用。
会话数据仍在存储器中无关紧要,因为它在到期后无法使用;当垃圾收集器下次运行时它将被删除。在session_start
次调用时,session.gc_probability除以session.gc_divisor的概率就会发生这种情况(另见How long will my session last?)。
修改由于您希望在已过期的会话上执行其他一些任务,我建议您使用custom session save handler。
当使用类作为会话保存处理程序时,您可以编写两个类,一个用于基本保存处理程序,另一个用于执行附加任务的扩展垃圾收集器,例如:
interface SessionSaveHandler {
public function open();
public function close();
public function read($id)
public function write($id, $data);
public function destroy($id);
public function gc($callback=null);
}
class SessionSaveHandler_WithAdditionalTasks implements SessionSaveHandler {
// …
public function gc($callback=null) {
if (!is_null($callback) && (!is_array($callback) || !is_callable($callback))) return false;
while (/* … */) {
if ($callback) $callback[0]::$callback[1]($id);
// destroy expired sessions
// …
}
}
public static function doAdditionalTasksOn($id) {
// additional tasks with $id
}
}
session_set_save_handler(array('SessionSaveHandler_DB_WithAdditionalTasks', 'open'),
array('SessionSaveHandler_DB_WithAdditionalTasks', 'close'),
array('SessionSaveHandler_DB_WithAdditionalTasks', 'read'),
array('SessionSaveHandler_DB_WithAdditionalTasks', 'write'),
array('SessionSaveHandler_DB_WithAdditionalTasks', 'destroy'),
array('SessionSaveHandler_DB_WithAdditionalTasks', 'gc')
);
答案 1 :(得分:1)
每个会话不调用垃圾收集器,垃圾收集器根据tge gc_ *值调用更改,这会使多个会话无效。因此,只要某人触发它,其他人就可以退出。如果你需要一个更可靠的方法,如果你的超时是几分钟,请使用cronjob,如果你的超时是几秒钟,你将不得不使用某种守护进程。
答案 2 :(得分:1)
如果您需要调用特定的过期逻辑(例如,为了更新数据库)并希望独立于请求,那么实现一个查看会话文件访问时间的外部会话处理程序守护程序是有意义的。 daemon script应该执行在指定时间内未访问的每个会话文件所需的任何内容。
此解决方案有两个先决条件:服务器的文件系统支持访问时间(Windows不支持),您可以从session save path读取文件。
答案 3 :(得分:1)
您可以这样做的一种方法是在超时期限后使用javascript刷新页面。当然,您的用户必须启用Javascript才能使用此功能。您还可以添加额外的功能,例如让javascript弹出超时通知和倒计时等等。因此,由于您的设置,然后刷新命中,清理运行和完成,会话过期会发生什么。
<html>
<head>
<script type="text/JavaScript">
<!--
function timedRefresh(timeoutPeriod) {
setTimeout("location.reload(true);",timeoutPeriod);
}
// -->
</script>
</head>
<body onload="JavaScript:timedRefresh(5000);">
</body>
</html>