【问题标题】:PHP Session expire eventPHP 会话过期事件
【发布时间】:2010-02-13 00:07:39
【问题描述】:

我正在尝试对开源项目进行一些更改。我想跟踪用户何时登录和注销。 现在,当他们登录或手动注销时,我在 db 中更改了他们的登录状态。现在的问题是我无法确定用户是否在没有按下注销按钮的情况下关闭了浏览器。 出于这个原因,我需要触发一个函数,每次用户会话到期时都会更改数据库。 我在 PHP 中尝试过session_set_save_handler,但看起来我需要覆盖整个会话行为。我正在寻找的是保持默认会话行为,并在用户会话到期时添加功能。有没有办法做到这一点?

【问题讨论】:

    标签: php session


    【解决方案1】:

    我曾经做过一次真的讨厌的事情。每次通过页面刷新/获取/等“更新”会话时,我都会更新数据库行上的时间戳。第二个守护进程每 10 分钟轮询一次数据库并执行“清理”操作。

    您不会找到任何原生 PHP 工具来实现您的目标。会话超时不在后台运行。您甚至不知道会话是否超时,除非超时会话尝试另一次访问。在这一点上,几乎不可能被困住,你可以下定决心,妥善处理。

    我建议针对这个问题使用队列和轮询架构。这很容易,而且肯定会奏效。如果您担心事务性能,请添加 memcached。

    【讨论】:

    • 我做过类似的事情。我做了一个函数,既可以更新用户最近的页面/活动,又可以轮询数据库以查找超过 2 分钟的非活动会话并清除它们。我想我可以用一块石头杀死两只鸟。凌乱,但无需创建 cron 作业即可完成工作。
    【解决方案2】:

    我假设您正在使用标准的基于 PHP 文件的会话。如果是这种情况,那么 PHP 将根据 php.ini 中的 session.gc_* 配置参数对陈旧会话进行自己的垃圾收集。您可以覆盖这些以完全禁用垃圾收集器,然后滚动您自己的 GC 脚本。

    您可以检查文件上的时间戳(使用 stat() 在循环中快速轻松地完成)以查找“旧”会话,或者解析每个文件中的数据以检查列出最后一个的变量 -访问时间。无论哪种方式,会话文件都只是serialize($_SESSION) 的输出,可以很容易地重新加载到另一个 PHP 实例中。

    【讨论】:

      【解决方案3】:

      javascript 上的窗口关闭事件怎么样。所以基本上当会话站点的所有窗口都关闭时会话被破坏。因此,当最后一个窗口关闭时(通过额外的 js 检查进行检查)向服务器发送 ajax 请求。

      【讨论】:

      • 好主意,但是仅仅因为您关闭窗口并不意味着会话结束,他们可以保持浏览器打开并重新加载网页,他们仍将使用原始会话。不仅如此,在同一个域中将一个网页留给另一个网页会触发 ajax 事件,该事件会在他们仍在访问该站点时从数据库中删除会话信息。如果有一个javascript事件来检查浏览器是否关闭,那就更好了。
      猜你喜欢
      • 1970-01-01
      • 2017-10-05
      • 2011-04-07
      • 2013-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-12
      • 2013-09-19
      相关资源
      最近更新 更多