0

这已经困扰我很久了,但我无法弄清楚..

基本上我正在使用一个计数器,它将唯一的 IP 地址存储在一个文件中。但我想做的是让它计算每个 IP 地址的命中次数。

因此,而不是文件读取:

222.111.111.111  
222.111.111.112  
222.111.111.113  

我希望它阅读:

222.111.111.111 - 5  
222.111.111.112 - 9  
222.111.111.113 - 41  

这是我正在使用的代码:

    $file = "stats.php";  
    $ip_list = file($file);  
    $visitors = count($ip_list);  

    if (!in_array($_SERVER['REMOTE_ADDR'] . "\n", $ip_list))  
    {  
    $fp = fopen($file,"a");  
    fwrite($fp, $_SERVER['REMOTE_ADDR'] . "\n");  
    fclose($fp);  
    $visitors++;  
    }

我试图做的是将其更改为:

    if (!in_array($_SERVER['REMOTE_ADDR'] . " - [ANY NUMBER] \n", $ip_list))  
    {  
    $fp = fopen($file,"a");  
    fwrite($fp, $_SERVER['REMOTE_ADDR'] . " - 1 \n");  
    fclose($fp);  
    $visitors++;  
    }

    else if (in_array($_SERVER['REMOTE_ADDR'] . " - [ANY NUMBER] \n", $ip_list))  
    {  
    CHANGE [ANY NUMBER] TO [ANY NUMBER]+1
    }

我想我可以弄清楚最后添加的部分,但是我如何表示该[ANY NUMBER]部分以便它找到 IP,无论以下数字是多少?

我意识到我可能做错了,但如果有人能给我一个线索,我会非常感激。

谢谢。

4

3 回答 3

1

这是个坏主意,不要这样做。

将网站静态数据存储在文件系统中是正常的,但不应用预聚合。

如果要使用文件系统,则对数据进行后聚合,否则使用数据库。

于 2012-07-19T03:44:55.510 回答
0

你在做什么是一个非常糟糕的主意

但是,让我们首先回答您提出的实际问题。

为了能够做到这一点,您必须首先在某种允许完成的数据结构中实际处理文件。我个人推荐一个 . 形式的数组IP => AMOUNT

例如(未经测试的代码):

$fd = file($file);
$ip_list = array();
for ($fd as $line) {
   list($ip, $amount) = explode("-", $line);
   $ip_list[$ip] = $amount;
}

请注意,代码并不完美,因为由于原始数据的性质,它会在末尾留一个空格,$ip在前面留一个空格。$amount但它足以为您指明正确的方向。更“准确”的解决方案将涉及正则表达式或将原始数据源修改为更方便的格式。


现在是您实际问题的真正答案

您的流程将很快成为性能瓶颈,因为您必须为每个请求打开该文件,对其进行处理并在之后再次将其全部写回(不确定您是否可以对打开的文件进行内联编辑)。

当您尝试进行某种每 IP 命中计数时,有很多更好的解决方案可以解决您的问题:

  • 使用现有的解决方案(如piwik
  • 为您的数据使用实际数据库
  • 仅使用 IP 列表保持文件简单,并定期离线对其进行后期处理,使其成为您想要的格式
  • 如果您可以访问网络服务器的日志(并且它们被设置为使用原始 IP 记录每个请求),您可以完全避免编写该文件,并且您可以改为对该文件进行后处理
于 2012-07-19T03:48:47.623 回答
0

in_array()只是做一个基本的字符串匹配。它不会寻找子字符串。忽略使用平面文件进行数据存储是多么糟糕的想法,您想要的是preg_grep,它允许您使用正则表达式

$ip_list = file('ips.txt');
$matches = preg_replace('/^\d+\.\d+\.\d+\.\d+ - \d+$/', $ip_list);

当然,这是一个非常基本且非常破碎的 IP 地址匹配,并且不会帮助您实际更改 $ip_list 中的值,因为您没有获得匹配行的实际索引。

于 2012-07-19T03:59:44.433 回答