Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/228.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于在会话超时时注销用户的php观察者模式_Php_Session_Timeout_Observer Pattern - Fatal编程技术网

用于在会话超时时注销用户的php观察者模式

用于在会话超时时注销用户的php观察者模式,php,session,timeout,observer-pattern,Php,Session,Timeout,Observer Pattern,我试图在用户会话超时时注销用户。在我的例子中,注销用户需要修改用户在数据库中的“在线”状态。 我在想,我可能可以使用observer模式来制作一些东西,监视用户会话的状态,并在会话到期时触发回调,这将保留用户名,以便我们可以更新数据库。我不确定该从哪里开始。我可以将回调绑定到会话超时吗 这些东西是否内置于任何可用的pear或zend会话包中?我会尽我所能让这一切发生 更新@16:33: 如果您有一个用户可以相互交互的系统(但他们只能与在线用户交互),该怎么办?用户需要知道当前哪些其他用户在线

我试图在用户会话超时时注销用户。在我的例子中,注销用户需要修改用户在数据库中的“在线”状态。
我在想,我可能可以使用observer模式来制作一些东西,监视用户会话的状态,并在会话到期时触发回调,这将保留用户名,以便我们可以更新数据库。我不确定该从哪里开始。我可以将回调绑定到会话超时吗

这些东西是否内置于任何可用的pear或zend会话包中?我会尽我所能让这一切发生



更新@16:33:
如果您有一个用户可以相互交互的系统(但他们只能与在线用户交互),该怎么办?用户需要知道当前哪些其他用户在线

如果我们只是在每次页面刷新时检查会话是否仍处于活动状态,那么在超时后,用户将被发送到未登录的页面,但他们在系统中仍被列为联机

这种方法很好,只是当我们超时会话时,我们会丢失可以用来注销他们的用户信息



更新@16:56:

正确的。谢谢我同意……有点难看。我已经对服务器进行了一些缓慢的轮询,因此实现该方法非常容易。对于会话处理包来说,它似乎是一个非常有用的特性。Zend和PEAR都有会话包

你为什么要这样做?常见的方法是检查用户发送的每个请求是否超时。当然,这意味着数据库中的状态不是最新的,因为即使已达到超时,用户仍显示为已登录


但出于实际目的,这通常并不重要。

丑陋但可能可行的建议:


向页面添加一个异步保持活动请求程序,该请求程序更新页面的最后一个活动时间戳。然后,您可以拥有一个cron作业,如果用户的最后一个活动时间戳超过20秒,则该作业会将用户标记为脱机。将cron作业设置为每分钟运行一次就可以了。我不确定是否有办法在用户会话超时或关闭浏览器时触发某些事件。

先举一个最简单的例子。假设您的系统上有1个用户,您希望他们的会话超时,并且希望准确报告他们的状态。用户在12分钟内未访问页面,会话超时设置为10分钟。有两件事会发生。要么他们会在短时间内再次访问,要么他们不会。如果他们不再访问,系统将如何运行代码来更新他们的超时状态?唯一的方法*是让一个单独的进程为当前处于“会话中”状态的所有用户启动状态更新功能

每次用户访问您的站点时,都要更新数据库中的一个变量,该变量将他们的会话与上次访问的时间关联起来。然后创建一个每分钟运行的cron作业。它调用一个简单的函数来检查会话状态。任何早于超时时间的会话都将设置为状态“超时”。(你也应该在超时的会议坐了一段时间后清理桌子)。如果您想要关于登录人数的报告,请查询上次访问时间晚于超时间隔开始时间的所有记录


“*”还有其他方法,但对于一个简单的web应用程序来说,这并不是必需的。如果您有比简单web应用更复杂的问题,请更新您的问题以反映特定需求。

我的第一个想法是,您可以创建一个自定义会话处理程序,将登录解释为具有活动会话


有关创建自定义会话处理程序的一些示例,请参见并阅读PHP文档,每当用户点击页面时,在数据库中标记该时间,调用此列LastAccessed。当用户单击站点的注销部分时,可以将此值设置为null。在编写查询以查找当前登录的用户列表时,请执行以下操作:

SELECT *  FROM Users WHERE LoggedIn=1 AND LastAccess > DATEADD(Minute,-20.GETDATE())

这将返回仍有活动会话的用户。请原谅SQL可能不适用于MySQL/PHP,但这应该会给您一个大致的想法。

我知道这可能是一个较老的问题,但您的问题的“最佳”答案可以在这里找到:

它是这样说的: ini文件包含一个名为sesison.save_path的设置,该设置确定php将包含会话数据的文件放在何处。一旦会话过时,它将在下一次垃圾收集期间被PHP删除。因此,对该会话是否存在fiel的测试应足以确定会话是否仍然有效

$session_id = 'session_id';
$save_path = ini_get('session.save_path');

if (! $save_path) {
$save_path = '.'; // if this vlaue is blank, it defaults to the current directory
}

if (file_exists($save_path . '/sess_' $session_id)) {
unlink($session_id); // or whatever your file is called
}

代替cron,在页面逻辑上做一个简单的用户检查(查找cookie,检查用户数据库记录上的“last_visited”列,等等)。因此,如果用户决定再次激活,您可以验证用户信息和活动,并且仍然能够重定向,因为标头尚未发送。您的逻辑已关闭<代码>!文件_exists()??