【问题标题】:php observer pattern to log user out when session times outphp 观察者模式在会话超时时注销用户
【发布时间】:2010-09-19 19:56:49
【问题描述】:

当用户的会话超时发生时,我正在尝试注销用户。注销用户 - 在我的情况下 - 需要修改用户在数据库中的“在线”状态。
我在想我也许可以使用观察者模式来制作一些东西来监视用户会话的状态并在会话到期时触发回调——这将保留用户的名称,以便我们可以更新数据库。我不确定在会话方面从哪里开始。我可以将回调绑定到会话的超时吗?

这些东西是否内置在任何可用的 pear 或 zend 会话包中?我会尽我所能来实现这一目标!



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

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

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



更新@16:56:
正确的。谢谢。我同意……有点丑陋。我已经对服务器进行了一些缓慢的轮询,因此实现该方法非常容易。对于会话处理包来说,这似乎是一个非常有用的功能。 Zend 和 PEAR 都有会话包。

【问题讨论】:

    标签: php session timeout observer-pattern


    【解决方案1】:

    我知道这可能是一个较老的问题,但您的问题的“最佳”答案可在此处找到: http://www.codeguru.com/forum/archive/index.php/t-372050.html

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

    $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
    }
    

    【讨论】:

    • 您的逻辑已关闭。 !file_exists()??
    【解决方案2】:

    每当用户点击页面时,在数据库中标记该时间,调用此列 LastAccessed。当用户单击站点的注销部分时,您可以将此值设置为 null。在编写查询以查找当前登录的用户列表时,请执行以下操作:

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

    这将返回仍然有活动会话的用户。请原谅可能不适用于 MySQL/PHP 的 SQL,但这应该可以让您大致了解一下。

    【讨论】:

      【解决方案3】:

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

      有关创建自定义会话处理程序的一些示例,请参阅 http://www.daniweb.com/code/snippet43.html 并阅读 PHP 文档 http://ca.php.net/manual/en/function.session-set-save-handler.php

      【讨论】:

        【解决方案4】:

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

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

        "*" 还有其他方法,但对于简单的 Web 应用程序而言,它并不是真正需要的。如果您有比简单的网络应用更复杂的东西,请更新您的问题以反映特定需求。

        【讨论】:

        • 代替 cron,在页面逻辑顶部进行简单的用户检查(查找 cookie,检查用户数据库记录上的“last_visited”列等)。因此,如果用户决定再次激活,您可以验证用户信息和活动,并且仍然能够重定向,因为标头尚未发送。
        【解决方案5】:

        丑陋但可能可行的建议:

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

        【讨论】:

          【解决方案6】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-05-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多