跟踪用户在我的网站上花了多少时间


Tracking how many hours users spend on my website

我正在编写一个用户系统,作为所有用户可用的统计数据,我希望能够向他们提供他们在我的网站上活跃的时间。

我最初的想法是:user加载页面,用户的记录存储在名为accessLog的SQL表中*用户加载另一个页面,SQL查询运行,看看他们最后一次访问的页面*如果用户在过去两分钟内访问了一个页面,则更新其用户帐户并添加在线时间*在accessLog中插入一条新记录*

然而,这将意味着增加4个额外的查询到我的网站的每一个页面的潜力,这似乎很慢。我在想,一定有一种更有效的方法来跟踪用户的在线活动,而我显然太笨了,看不到!

我的方法很简单:
  • 当用户加载一个页面时,他们的"最后一个页面加载时间"在数据库中更新。
  • 每分钟运行一个cron脚本。它查找"最后一个页面加载时间"在最后一分钟的用户。
  • 为每个找到的用户增加"在站点上花费的时间"。

通过这种方式,我可以精确到分钟地跟踪用户。除以60就得到小时数。

我会使用ajax让客户端每分钟调用一次服务器。只是告诉服务器用户还在看那个页面。

  • 服务器将在数据库中有一个lastTimestamp和一个totalTimeSpentOnSite。lastTimestamp只包含ajax请求或页面加载的最后一次时间。

  • 每次ajax触发时,服务器将计算now - lastTimestamp并将其添加到totalTimeSpentOnSite.

为了更准确,你可以
onBlur()添加javascript侦听器,只记录该窗口活动的实际时间,然后将该时间发送到服务器,而不仅仅是告诉服务器用户仍然活动。

我的哲学是:不要过分关注效率,直到它成为一个问题。除非你的网站流量很大,否则你不会注意到这四个查询。这可能更简单:

    记录每次页面加载。
  1. 每隔几个小时,通过cron运行一个计算时间的脚本每个用户的在线花费,并更新该用户的运行总数表。
  2. 定期清空access_log表

将其添加到会话管理中。当用户开始会话时,记录他们的开始时间。当用户结束会话时,记录其结束时间。通过简单的计算,你就能得到他们每次在你网站上花费的时间。


回答philip Haglund

是的,但是你必须等待会话超时,而这个时间并不能反映用户在他/她关闭前在最后一个页面上花费的实际时间。

这是真的,但是,到目前为止,所有可用的答案都是在相同的基本前提下工作的:

  1. 记录页面加载时间
  2. 用户离开
  3. 时的日志
  4. 更新数据库表

当用户离开时,恰好需要记录会话。我不知道PHP中还有什么其他方式可以像OP希望的那样跟踪用户活动。更新数据库表是一个技术问题。您想使用CRON作业吗?您想使用AJAX吗?你想做点别的吗?

如果你真的想知道实际发生了多少活动,你可以为某些JavaScript事件发送AJAX请求。这将把时间跟踪与实际的浏览器事件联系起来。当然,这意味着您的时间跟踪依赖于启用JavaScript。

"两分钟"规则有点不可靠——你可能会被试图弄清楚"花时间"的实际含义所束缚。

在上一个项目中,我们做了以下工作。

在每次页面加载时,我们检查用户是否有当前会话,如果没有,则创建一个GUID来标识当前会话。

我们向数据库写入了一条日志记录,其中包含日期时间、GUID、页面URL和用户ID(如果用户已经登录)。

为了计算"花费的时间",我们计算会话GUID的第一条和最后一条记录之间的时间差,并添加一分钟来反映在最后一页上花费的时间。

这并不完全准确,但是对于流量适中的站点,它可以实时运行而不需要CRON。

  • 首先选择会话被认为中断的持续时间。(例如:10分钟)
  • 记录所有页面加载与所有ip在数据库
  • 如果一个ip的两个页面加载之间的时间超过持续时间,则不将此时间添加到该ip的总时间
  • 如果一个ip的两个页面加载之间的时间小于持续时间,将此时间添加到该ip的总时间

2的问题是:-如果用户停留超过持续时间(10分钟)在一个页面没有刷新,他被认为是断开连接。-最后一页持续时间不保存

Piwik是这样工作的

这就是我使用的,它在用户加载任何页面时检查更新DB。数据是准确的,因为它计算用户是否每分钟加载一个页面,如果是,它将时间差添加到数据库中。

  $now= time();
 $stmt = $db_con->prepare(" SELECT last_seen,time_online FROM user_online_log  WHERE user_id=?  limit ?  ");
     $stmt->execute(array( $user_id, 1));       
     $fetch= $stmt->fetch(PDO::FETCH_ASSOC);  
   $last_seen=$fetch['last_seen'];  //integer value from db, saved from time() function
  $last_seen_plus_one_min= $last_seen + 60;
  if(  $now  <   $last_seen_plus_one_min   ){ 
  $additional_time_online= $now -   $last_seen; }
  else{ $additional_time_online = 0; }

     //update db
 $stmt12 = $db_con->prepare(" update user_online_log set   last_seen=?, time_online = time_online+? WHERE user_id=?  limit 1  ");
 $stmt12->execute(array($now, $additional_time_online,  $user_id));