0

为了简单起见,假设我在 php 中制作了一个基本的浏览量计数器,它将每个页面的计数存储在一个 mysql 表中。该表有 2 个列:PAGE_ID 和 COUNT。

我将以下代码添加到每个页面:

$query = "INSERT INTO table VALUES ('$page_id', '1')
         ON duplicate KEY UPDATE COUNT=COUNT+1";

$result = mysqli_query($cxn, $query);

为了确保每个查看页面的人只在我添加 PHP 会话后触发计数器。基本上,如果您查看页面,page_id 会存储在会话中,并且计数器 php 代码会在触发计数器之前检查该会话。在我自己的测试中运行良好。

有些页面的浏览量过多,我怀疑重复,所以我开始记录 IP 和用户代理。事实证明,在大约 10% 的情况下,IP 会在几分钟内触发同一页面的计数器 2-3 次。

第一个问题 什么可能导致重复?这个问题似乎主要发生在 IE8 和 Safari 上,但我也至少有一个实例发生在 IE7 和 IE6 上。php会话有任何已知问题吗?我应该改用 cookie 吗?

第 2 部分:我修改了我的表,以便它现在存储最后一个 unix 时间戳和触发计数器的最后一个 IP。

我想修改我的查询,以便在它运行“COUNT=COUNT+1”之前检查以下内容:

If the current IP is the same as the last stored IP for this page {

     check that it's been at least 5 minutes before doing COUNT=COUNT+1

} else { COUNT=COUNT+1; }

第二个问题 我如何在 mysql 查询中编写它,同时保持我的“ON duplicate KEY”语句?

我知道这个陈述不会 100% 准确,但在我弄清楚为什么会话的事情似乎不起作用之前,这会起作用。我的网站流量很低,在 5 分钟的时间内我很少在同一页面上获得超过 1 个访问者。

谢谢

4

4 回答 4

2

我建议您尝试查看是否可以修复 PHP,但忽略它。您可以存储 unixtimestamp 除以 300(IE,以 5 分钟为间隔)

$query = "INSERT INTO OtherTable VALUES ('$page_id', '$IP_ADDRESS', (UNIX_TIMESTAMP(NOW())/300))";

如果更新的记录为 0,则不需要更新页数。

于 2009-12-20T18:36:53.677 回答
1

1. 什么可能导致重复?

有些页面的浏览量过多,我怀疑重复,所以我开始记录 IP 和用户代理。事实证明,在大约 10% 的情况下,IP 会在几分钟内触发同一页面的计数器 2-3 次。

无法知道请求页面的主机是否位于 NAT 路由器后面 - 对您而言,请求将具有相同的 IP,但实际上是不同的主机。cookie 或会话将帮助您在每个工作站的基础上进行隔离,但我想知道您何时将信息写入数据库。

2. 我如何在 mysql 查询中编写它,同时保留我的“ON duplicate KEY”语句?

我认为不需要COUNT = COUNT + 1,因为 SQL 有一个 COUNT 函数:

  SELECT page_id,
         COUNT(*) 'num_hits'
    FROM ZZZ_NETWORK
   WHERE page_id = ?
GROUP BY page_id

如果您使用以下结构ZZZ_NETWORK

  • page_id,主键
  • ip_address,主键
  • 时间戳,主键

...您不必担心重复的密钥处理,它可以让您知道您在特定的一天、一周、一个月/等中获得了多少次点击。 包括时间戳将确保永远不会有重复

一个月后,如果我在每个页面视图中使用一行,我的表中就会有数千行。

驱动器空间非常便宜,并且具有时间戳以便您可以进行数据挖掘对于报告而言非常宝贵。但是您也不必保留所有数据 - 您可以通过将数据转储到文件来归档它,以便在必要时检索它。

我不明白它如何确保我永远不会得到重复。

时间戳包括日期(2009 年 12 月 25 日)和时间(07:00:00 AM)。某些日期时间数据类型可以精确到几分之一秒。这使得具有给定 IP 地址的给定 page_id 具有相同的日期和时间几乎是不可能的——即使我想,我也无法足够快地单击刷新按钮。所以记录永远不能重复,因为三列中的最后一列每次都会有不同的值(没有双关语的意思)。

于 2009-12-20T17:16:00.217 回答
0

你正在寻找的是一个CASE声明:http ://dev.mysql.com/doc/refman/5.0/en/case-statement.html

一个示例CASE语句:

SELECT name,
       (CASE WHEN is_happy THEN "Happy!"
        ELSE "sad." END) as happiness 
FROM user_state;

它们也可以用于UPDATEINSERT

我怀疑你想看看 IE 的东西,而不是。过去我也遇到过类似的问题,最后我不得不使用 javascript 来消除点击次数。我不确定是 IE 用户双击东西还是 IE 很奇怪。

于 2009-12-20T17:08:34.030 回答
0

我想我可能会找到解决会话问题的方法。实际上,我从会话切换到 cookie。

我的很多页面都通过 iframe 获得视图。iframe 导致 IE 浏览器出现问题。除非我添加 p3p 标头,否则 IE 无法从 iframe 中读取 cookie 数据。

我添加了 p3p 标头,现在它似乎工作正常。我厌倦了微软和他们的安全理念。我也不知道 p3p 是什么,但这就是它在 php 中的样子。

header ( "p3p:CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"");
于 2009-12-20T23:02:49.987 回答