PHP计数器仅溢出1字节数据,计数器复位(竞争条件)

PHP计数器仅溢出1字节数据,计数器复位(竞争条件),php,race-condition,integer-overflow,hitcounter,Php,Race Condition,Integer Overflow,Hitcounter,我知道这是一个简单的问题,但我从 这是google上第一个针对PHP计数器脚本的结果,正如预期的那样效果很好 在255个请求溢出回0后,我试图通过在浏览器中保持刷新来查看它是否出错。如何修复此脚本?我认为罪魁祸首是filesize(),它可能只获得1字节的数据,但它没有意义,因为255实际上是3字节的数据,对吗?因为它以纯文本格式保存 为什么会溢出?它甚至是PHP,它不应该溢出,只是自动变异成更大的数据类型 <?php $orderCountFile = "order_num_co

我知道这是一个简单的问题,但我从

这是google上第一个针对PHP计数器脚本的结果,正如预期的那样效果很好

在255个请求溢出回0后,我试图通过在浏览器中保持刷新来查看它是否出错。如何修复此脚本?我认为罪魁祸首是
filesize()
,它可能只获得1字节的数据,但它没有意义,因为
255
实际上是
3字节的数据,对吗?因为它以纯文本格式保存

为什么会溢出?它甚至是PHP,它不应该溢出,只是自动变异成更大的数据类型

<?php
    $orderCountFile = "order_num_count.txt";
    if (file_exists($orderCountFile)) {
        $fil = fopen($orderCountFile, r);
        $dat = fread($fil, filesize($orderCountFile)); 
        echo $dat+1;
        fclose($fil);
        $fil = fopen($orderCountFile, w);
        fwrite($fil, $dat+1);
    } else {
        $fil = fopen($orderCountFile, w);
        fwrite($fil, 1);
        echo '1';
        fclose($fil);
    }
?>

是的,我开始将脚本重新制作成另一个用途,我想用它来跟踪我网站的订单号

为了解决这个问题,我想我必须将
$dat
重新编译成一个更大的整数类型,但是你甚至可以在PHP中转换吗


还有那些
r
w
我认为应该是字符串,但它们被用作常量,但似乎不会引起任何问题。

使用
file\u get\u contents
file\u put\u contents
。您还必须考虑,该计数器也有一个硬限制(参见<代码> PHPyItIn Max ),但它明显更高。

<?php
$file = "counter.txt";
$counter = 0;
if (file_exists($file)) {
  $counter = file_get_contents($file);
}

$counter = $counter + 1;
file_put_contents($file, $counter);
echo $counter;

一个字节可以表示数字0-255。是的,我错了,它不会溢出,但会重置为0。。如果你很快刷新脚本。。这可能是一个读/写争用问题,但我仍然无法解决。哦,我发现了一个相关的问题,可能与我认为的问题相同,可能是多个脚本同时访问同一个文件系统并导致争用情况,如线程?它似乎并没有停在
255
。。我错了,现在它上升到了280。但是它仍然有漏洞。是的,但是如果不锁定那些
file\u get\u内容
/
file\u put\u内容
,比赛条件是否仍然可能?或者它们安全吗?是的,这仍然适用。当您将第三个参数添加到
file\u put\u contents
:标志
EX\u LOCK
时,可能会阻止重置。但在重载期间,您仍然可以跳过读写操作之间的一些计数器,在这种情况下,基于文件的计数器可能根本不是一个好的解决方案。我是否可以让其他php脚本在读取之前暂停,以便在前一个脚本完成之前不获取过时的值?这正是链接帖子中的解决方案所做的,如果在创建句柄后锁定文件,那么就没有其他(php)进程可以在句柄关闭或解锁之前读取文件。但还有一条评论提到了用于此操作的数据库,因为它们已经内置了并发性。