【问题标题】:Can I count sessions to determine number of people online?我可以计算会话数以确定在线人数吗?
【发布时间】:2012-08-10 16:42:15
【问题描述】:

我对某事感到困惑。当我尝试搜索如何在 PHP 中统计在线用户时,所有答案都与 MySQL 和许多不同的方式相关。

在我的脚本中,任何提交登录表单的用户都会创建一个 $_SESSION['$nickname']

所以我想,我可以用 count($_SESSION['$nickname']); 计算登录会话数吗?并显示在我的页面中?

或者这完全是一个错误的逻辑?

【问题讨论】:

    标签: php mysql session


    【解决方案1】:

    这是错误的逻辑,会话仅在最终用户的 PC 上本地存储并立即销毁,因此如果没有用户做某事,就无法从服务器读取它以进行任何确认。服务器端会话仅在垃圾清理时被销毁。

    最好的办法是为每个用户设置一个时间戳,该时间戳在用户执行任何操作时都会更新。这意味着您需要通过 JS/AJAX、PHP 触发此更新。然后,您可以查看最近 5 分钟内有多少时间戳,这可以让您大致了解当前有多少用户在线。

    您还可以有一个隐藏的 iframe,它每隔几秒不断刷新并更新时间戳,或者 JS/AJAX 也每隔 X 秒更新一次时间戳......

    【讨论】:

    • “这是错误的逻辑,会话仅本地存储在最终用户的 PC 上”这是 Cookie 而非会话的真实信息。
    • 是的,但我想我应该澄清一下,当浏览器关闭时会话会立即(本地)销毁,但不会在服务器上。服务器可以保留更长时间。
    【解决方案2】:

    首先,您必须定义“在线”的含义。 用户是否应该在过去 5 分钟内点击过链接?

    我假设您的数据库中已经有一个用户表。 所以最简单的方法是添加一个新列,例如lastAction TIMESTAMP.

    当用户点击你页面上的链接时,你的脚本应该更新这个值。

    在您的统计页面或其他页面上,您可以使用该代码获得在线用户的数量:

    SELECT COUNT(*) FROM users WHERE lastAction > (NOW() - 60*5)
    

    【讨论】:

    • 是的,这是很好的信息,但它会创建太多的 MySQL 连接和更新。我只想计算创建会话的用户。我们知道如果他们关闭浏览器或关闭我的网站,会话将被破坏。
    • 如果您只想统计当前会话(文件)的数量,Marc B 已经发布了您的解决方案。
    • 顺便说一句,我真的很喜欢 lastaction 计算在线用户的方式。会不会累到服务器?因为,每个页面都会更新,你知道的。
    • 为什么INTEGER 顺便说一句?你把它比作时间,那为什么不TIMESTAMP
    • @Slavez 这取决于您的服务器和您拥有的用户数量。但它并没有你想象的那么贵。
    【解决方案3】:

    PHP 在会话存储方面非常灵活,您可以定义自己的会话保存/恢复处理程序。

    但是,默认会话存储是files,其中每个会话单独存储到磁盘。这意味着,为了找出有多少用户有“online”(这里,我假设“online = session 存在$_SESSION['$nickname']set”),你将需要打开存储在磁盘上的所有会话文件,并检查其中存在多少个唯一昵称。这在时间和所需资源方面都非常繁重。

    因此,大多数教程建议在数据库中计算这一点,方法是维护每个用户的最后一次看到的时间戳(并检查有多少用户在最近 X 分钟内最后一次看到)。

    如果您希望合并,可以通过定义自己的会话保存处理程序来将会话信息存储在数据库中...


    关于会话的几个附加说明:

    • 关闭浏览器时不会立即销毁会话。事实上,浏览器不会以任何方式告诉服务器它正在关闭。这意味着服务器应该提出一些基于时间的算法来决定谁在线,谁不在线。
    • 会话彼此隔离,因此$_SESSION["foo"] 不能被多个不同的会话共享 - PHP 中没有与Global.asa 等效的选项。不是开箱即用。

    【讨论】:

      【解决方案4】:

      完全错误的逻辑。 $_SESSION 是每个用户的事情。一个用户的会话不与任何其他用户的会话共享。想想看 - 一个用 PHP 编写的在线银行,都共享一个 $_SESSION - 每个人都会看到每个人的帐户详细信息。

      假设您使用的是标准的基于 PHP 文件的会话,您可以在它们存储的任何目录中计算会话文件,例如

      $users = count(glob(session_save_path() . '/*'));
      

      请注意,这仅计算会话文件 - 它无疑会包含尚未被垃圾回收的陈旧/死会话。如果你想要一个真正的“现在真的在线”,你必须解析每个会话文件并检查它的内容。

      【讨论】:

      • 这很有帮助,我将根据这些信息进行一些更改,谢谢。
      • 这里有两个问题:(1)不是每个会话都可能有一个nickname,(2)这些昵称不一定是唯一的......
      • 哦,关于垃圾收集的文件...您可以使用find(执行)查看过去 N 分钟内修改了多少会话文件...
      • 您可能会研究如何将此应用程序的会话存储在不同的目录中,还为它们设置较短的生命周期(但要小心 - 不要太短)然后执行等效的“-latr”和只计算最近 x 分钟内创建的内容。
      猜你喜欢
      • 2011-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多