PHP计数器仅覆盖/溢出1个字节的数据,计数器重置(竞争条件)

时间:2014-05-30 22:53:01

标签: php race-condition integer-overflow hitcounter

我知道这是一个简单的问题,但我从http://www.stevedawson.com/scripts/text-counter.php

下载了一个PHP Counter脚本

这是google for PHP计数器脚本的第一个结果,它按预期效果很好。

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

为什么会溢出?它甚至是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进行转换吗?

另外那些rw被认为是我认为的字符串,但它们被用作常量,但它似乎不会引起任何麻烦。

1 个答案:

答案 0 :(得分:1)

改为使用file_get_contentsfile_put_contents。你仍然需要考虑,该计数器也有一个硬限制(见PHP_INT_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;