【问题标题】:PHP/MySQL Update database on session timeoutPHP/MySQL 在会话超时时更新数据库
【发布时间】:2014-07-17 15:10:12
【问题描述】:

我正在开发一个“flash 网站”。在这个程序中,我想添加一个“在线用户”列表,它依赖于会话:用户登录时启动会话,并且用户在数据库中被标记为在线。一旦退出关闭浏览器,用户在数据库中被标记为离线。

我知道在浏览器关闭时运行某些功能需要 Javascript,而且也不安全:如果浏览器崩溃,这些功能将无法运行。这就是为什么我决定在用户​​注销或用户的 session 超时时更新数据库。

我一直在查找会话超时,并遇到了这个问题,还有许多其他类似的标记为重复:How do I expire a PHP session after 30 minutes?

答案方法的问题是;这是一个条件语句,检查用户的最后一次活动是否是 X 秒前,如果没有活动,则超时。在某些网站中有用,但对在线用户列表无用,因为它会在发送新请求时更新,并且在用户关闭浏览器后不会有任何请求。

其他答案中还提到了session.gc_maxlifetimesession.cookie_lifetime 的使用,但最佳答案指出使用它们是一个坏主意;一种不会破坏会话,只是 cookie,另一种是“成本密集型”。

我想要的是用户超时和数据库更新并将用户标记为离线不使用使用 If-Conditional 句子,或者可能使用不同的 If-conditional 句子,仅必须在用户登录时使用一次,例如计时器或其他东西,并且每当发送请求时,计时器都会重新启动...这些只是我目前关于如何解决此问题的想法。

但是,我该怎么做呢?如果答案非常简单明了,我很抱歉,我对 PHP 很陌生。

编辑:长话短说:

我想在用户关闭他的浏览器后运行一个函数,或者20分钟不活动。

澄清...

我想在闲置 20 分钟后更新数据库即使浏览器已关闭。

【问题讨论】:

    标签: php mysql session cookies timeout


    【解决方案1】:

    我想在浏览器运行 20 分钟后更新数据库 关闭。

    我不认为这真的可能与关闭浏览器(可靠地)有关。如果他们单击注销按钮,您显然可以运行一些代码将用户标记为已注销。您可以使用您提到的功能指定会话的有效时间,但这所做的只是使 cookie 在客户端被删除,它不会在服务器端触发任何东西。

    您唯一能做的就是跟踪用户上次活动的时间,如果他们有一段时间没有活动,则假设他们已经离开。因此,只需将一个字段添加到您的用户表并存储他们上次活动的日期时间或 unix 时间戳。然后,您可以每隔几分钟运行一个 cron 作业,将用户标记为已注销,或者您可以简单地修改 SQL 查询以仅提取最近一次活动少于 20 分钟前的用户。

    【讨论】:

    • 我更新了问题以获得更多说明;我想在闲置 20 分钟后更新数据库即使浏览器已关闭。有没有办法让服务器或数据库自行启动功能? PS:非常感谢您的回答!如果没有其他解决方案,我将使用您的解决方法,我没想过只拉动具有特定活动时间的用户。
    • 正如我在回答中所说,您可以有一个每隔几分钟运行一次的 cron 作业,它会调用一些 php 代码。
    • 啊,那部分没看懂,我还以为是错字。那么,什么是 cron 工作? xD
    • 在 linux 服务器上,cron 作业只是一个调度程序,您可以设置一个每分钟、每 5 分钟、每天一次、每月一次等运行的 cron 作业......如果你这样做一个简单的谷歌搜索你会发现更多的信息。
    【解决方案2】:

    您可以借助带有最后一个活动字段的在线用户表来完成此操作,

    window.setInterval(function() {
        $.ajax({      
          url: "http://yourdomain/updateLastactive/?uid=" + User_ID,
          success: function(data) {
    
          }
        }); 
    }, 5000); // 5 seconds 
    

    此页面会将当前时间戳更新为该用户的最后一次活动

    然后在线用户查询你可以像下面这样,

    SELECT UID FROM ONLINE_USERS WHERE LAST_ACTIVE >  DATE_SUB(NOW(), INTERVAL 30 MINUTE));
    

    【讨论】:

    • 很抱歉问了这么一个无聊的问题,但是......我把第一部分放在哪里?我对 Java/Ajax 没有任何经验。
    • 你需要写在document ready函数里面,如下所示
    • 只是为了确保,Javascript 部分所做的唯一事情就是更新该用户的上次活动时间吗?
    • 是的,JavaScript 仅用于调用上次活动的更新数据库。
    • 嗯,非常感谢您的回答,但还有另一个答案建议仅使用 mysql 和 php 的方法。我会接受这个答案,但我会奖励你的努力。再次感谢! ^^
    【解决方案3】:
    if (!isset($_SESSION['CREATED'])) {
        $_SESSION['CREATED'] = time();
    } else if (time() - $_SESSION['CREATED'] > 1800) {
        // session started more than 30 minutes ago
        session_regenerate_id(true);    // change session ID for the current session an invalidate old session ID
        $_SESSION['CREATED'] = time();  // update creation time
    }
    

    也读过这个 http://php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime

    【讨论】:

    • 这与我一直在谈论并链接到的 If-conditional 相同:/ 你的意思是即使我在每个请求中都不使用 if Conditional,只是登录,它会30 分钟后超时?
    • 您可以根据需要在条件内修改此脚本。
    • 即使我修改了它,关闭浏览器后它仍然无法运行。我的问题是,如何在 X 分钟后使会话超时 而不必在 X 分钟后运行新的条件。
    【解决方案4】:

    您想通过使用此处的信息来捕捉事件: How to capture the browser window close event?

    然后,您将需要在服务器上使用 sessionID 在该事件处理程序中调用的页面。

    该页面调用您设置为延迟 20 分钟并使会话到期的本地脚本、页面或服务。如果您想在用户在到期前重新访问时重新启动时钟,您将需要包含一种中断或取消该脚本进程的方法,并且您需要将 SessionID 保留在 cookie 中,每次页面加载时都需要查找该 SessionID .如果 cookie 的 SessionID 被找到并且匹配,超时被中断/停止(如果它还在继续)。如果已经完成,则需要发布一个新的 SessionID。

    如果您同时有很多这样的取消,您将改为在服务器上排队,并让一个进程定期检查队列并根据需要使它们过期。

    大多数网站避免这一切的方法是设置 30 分钟或任何会话超时,无论访问者是否活跃。

    【讨论】:

    • 相当不错的解决方案,但就像我提到的,如果浏览器崩溃,它很可能无法工作。你回答的最后一行,这就是我的问题的全部内容,我想知道如何做到这一点,但我不能使用链接中提到的功能,因为页面关闭后我将无法运行它...那么,如何设置“30 分钟会话”?
    • 这里有另一个关于普通会话超时的答案。这将在页面重新打开时运行,但在浏览器崩溃且页面未重新打开时不会运行。我能想到跟踪的唯一原因是您是否正在跟踪活动会话计数或其他内容。最好的方法是将时间戳和 sessionid 存储在服务器上的表中,并定期运行脚本以更新或删除超时行。
    【解决方案5】:

    最简单的方法是编写一个 MySQL 存储过程,它查看会话时间戳并在会话数据超过 20 分钟时删除它。您也可以将其作为外部 cron 作业执行,但存储过程会更好。

    另外,每次用户连接时都需要刷新会话时间戳。

    如果您想确保在用户仍然打开您的“页面”时不删除会话,那么一些后台 JavaScript 刷新到您的网站将起到保持活动的作用。请注意,如果用户关闭“窗口”或“选项卡”,则与关闭整个浏览器相同 - 我不确定您是否可以对此做任何事情。

    当然,要做到这一点,您需要将会话存储在 MySQL 中。

    TL;DR

    • 如果 session_timestamp > 20min,MySQL 存储过程或 cron 作业将删除会话
    • 客户端 Javascript 执行 ajax 刷新以保持会话打开
    • 每次请求“页面”(浏览器或 ajax)时都会更新会话时间戳。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-23
      • 1970-01-01
      • 2013-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-05
      相关资源
      最近更新 更多