【问题标题】:PHP counter still loses hits after file locking?文件锁定后PHP计数器仍然丢失命中?
【发布时间】:2012-07-18 08:45:16
【问题描述】:

我使用的是以下基本 PHP:

<?php

    if (file_exists('count_file.txt')) 
    {
        $fil = fopen('count_file.txt', r);
        $dat = fread($fil, filesize('count_file.txt')); 
        echo $dat+1;
        fclose($fil);
        $fil = fopen('count_file.txt', w);
        fwrite($fil, $dat+1);
    }

    else
    {
        $fil = fopen('count_file.txt', w);
        fwrite($fil, 1);
        echo '1';
        fclose($fil);
    }
?>

作为一个命中计数器(我宁愿没有一个,但我们坚持要这样做)。 txt 文件记录了点击次数并且它可以工作......但是计数器随机(有时在几周后,有时在几个月后)决定跳闸并从 4300 下降到 11。

有人告诉我解决这个问题的方法是使用文件锁定,所以我更改为以下代码:

<?php 

        $dat = file_get_contents('count_file.txt'); 
        $fil = fopen('count_file.txt', 'w'); 
        if (flock($fil, LOCK_EX)) { 
            echo $dat+1; 
            fwrite($fil, $dat+1); 
            flock($fil, LOCK_UN); 
        } 
        fclose($fil); 

    ?> 

现在几天后,它再次从 5000 多个下降到 13 个。有人知道为什么吗??

【问题讨论】:

  • 为什么不在数据库中存储计数?如果需要在外部文件中,然后运行一些脚本来获取命中数?
  • 我不懂 PHP,所以不知道如何将它存储在数据库中?

标签: php counter


【解决方案1】:

您 fopen() 用于写入的文件会截断文件。如果您无法获得锁定,则关闭可能会被截断为零字节的文件。

【讨论】:

  • 如果他没有得到锁通常意味着它被锁定了。那他怎么能把它截为零呢?
  • 我认为这至少会发生在进程 A(持有锁)已写入文件并且进程 B 在文件被 A 解锁和关闭之前打开文件进行写入时。
【解决方案2】:

使用 fopen "a" 代替 fopen "w" 然后截断文件:

<?php
    $dat = file_get_contents('count_file.txt'); 
    $fil = fopen('count_file.txt', 'a'); 
    if (flock($fil, LOCK_EX)) { 
        ftruncate($fil,0);
        echo $dat+1; 
        fwrite($fil, $dat+1); 
        flock($fil, LOCK_UN); 
    } 
    fclose($fil); 
?> 

【讨论】:

    猜你喜欢
    • 2022-01-19
    • 1970-01-01
    • 2018-10-21
    • 2012-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-14
    相关资源
    最近更新 更多