PHP - 如何检测损坏的会话结束日期时间?

时间:2011-01-25 11:58:02

标签: php session session-state

用户案例:我需要跟踪用户在网站上的持续时间。计算方式为(结束日期时间 - 开始日期时间)。如果用户单击注销,这可以正常工作。然后系统可以记录结束日期时间。但我在边缘情况下的问题: 用户会话由于 - 用户端的互联网连接丢失,浏览器关闭,系统停机等等而结束。在这些情况下,系统如何知道结束日期时间,以便我可以计算持续时间。需要计算结束日期时间为关闭尽可能真实的日期时间。如果这是不可能的话,那么最多5分钟就可以了。

我看到的一种可能的方法是继续ping客户端系统并检查是否有效。但我不想这样做,因为它增加了不必要的带宽。那么任何其他方法来获取边缘情况的这些信息?

3 个答案:

答案 0 :(得分:3)

为什么不检查最后一次网页浏览的时间?

检查浏览器窗口的开放时间对于像我这样喜欢打开标签的人来说不会有太大作用...更不用说覆盖所有边缘情况(浏览器不是很难)支持JS,代理人背后的人等)。最后一次网页浏览应该精确到几分钟,它将具有最小的开销/复杂性,同时仍保持不错的准确度......

答案 1 :(得分:2)

实际上,系统无法知道结束时间,因为HTTP基本上是无状态协议。 PHP会话(以及其他Web脚本语言中的类似功能)是实现看似有状态的东西的黑客攻击,但这种黑客攻击无法完全克服HTTP的无状态特性。例如,正如您所发现的那样,如果用户没有通过“注销”过程,则服务器无法知道用户是否已注销。

您可以使用AJAX来ping用户,但正如您所说,这会使用带宽。如果用户关闭了javascript支持,它也将无法运行。

唯一明智的选择是在用户每次登陆系统的页面时记录用户的时间戳,并查看自时间戳更新以来的时间长度。如果超过合理限制,比如说20分钟,那么您可以假设用户不再在您的网站上。同样,这不是完全理想的,因为用户可能刚刚出去吸烟或其他东西,但由于HTTP是无状态的,因此无法实现的解决方案完全是理想的。

答案 2 :(得分:0)

跟踪用户会话的上次活动时间 - 基本上是在每个客户端请求中,您根据请求的时间更新会话记录。如果您还存储了登录时间,那么您始终可以计算会话的长度,无论它是活动的,不活动的还是用户已注销。我还在会话表中放置了一个'logged_out'标志,如果用户主动注销,它将被设置。

以下是我的会话表的定义:

CREATE TABLE IF NOT EXISTS `session` (
  `id` int(11) NOT NULL auto_increment,
  `php_session_id` varchar(100) NOT NULL default '',
  `ip_addr` varchar(100) NOT NULL default '',
  `login_time` datetime NOT NULL ,
  `activity_time` datetime NOT NULL ,
  `user_id` int(11) NOT NULL default '0',
  `logged_out` tinyint(1) NOT NULL default '0',
  PRIMARY KEY  (`id`),
  KEY `session_id` (`php_session_id`,`ip_addr`),
  KEY `user` (`user_id`,`logged_out`)
) ;