【问题标题】:Integer number truncated when writing to text file in PHP?在 PHP 中写入文本文件时整数被截断?
【发布时间】:2010-11-01 14:14:16
【问题描述】:

我写了一个下载计数器:

$hit_count = @file_get_contents('download.txt');
$hit_count++;
@file_put_contents('download.txt', $hit_count);

header('Location: file/xxx.zip');

就这么简单。问题是统计数字被截断为 4 位数字,因此不显示实际计数:

http://www.converthub.com/batch-image-converter/download.txt

批处理图像转换器程序每天被下载几百次,PHP 计数器已经使用了几个月。我第一次发现这一点是在大约 2 个月前,当时我很高兴它在几周后达到了 8000 大关,但一周后又回到了 500 大关。它一次又一次地发生。

不知道为什么。为什么?

【问题讨论】:

    标签: php file integer


    【解决方案1】:

    您可能在文件系统中遇到了争用情况,您正试图打开和读取一个文件,然后打开同一个文件并写入它。当您关闭文件进行读取然后立即再次打开文件进行写入时,操作系统可能尚未完全释放其对文件的原始锁定。如果网站如您所说的那样繁忙,那么您甚至可能会遇到多个脚本实例试图同时访问该文件的问题

    如果做不到这一点,请一次性完成所有文件操作。如果您使用 fopen ()、flock ()、fread ()、rewind ()、fwrite () 和 fclose () 来处理命中计数器更新,您可以避免关闭文件并再次打开它。如果您使用 r+ 模式,您将能够读取该值,将其递增,然后一次将结果写回。

    这些都不能完全保证您不会遇到并发访问问题。
    我强烈建议您研究一种不同的方法来实现您的命中计数器,例如数据库驱动的计数器。

    【讨论】:

    • 或者至少用flock锁定文件...$f = fopen('download.txt', 'r+'); flock($f, LOCK_EX); $hit_count = fread($f, 4048); $hit_count++; fseek($f, 0); fwrite($f, $hit_count); flock($f, LOCK_UN); fclose($f);
    【解决方案2】:

    始终进行正确的错误处理,不要只使用@ 抑制错误。在这种情况下,file_get_contents 很可能失败,因为当时正在写入文件。因此,$hit_count 设置为FALSE$hit_count++ 设置为1。因此,每当读取失败时,您的计数器都会随机重置为 1

    如果您坚持将数字写入文件,请进行适当的错误检查,并且仅在您确定文件已打开时才写入文件。

    $hit_count = file_get_contents('download.txt');
    
    if($hit_count !== false) {
        $hit_count++;
        file_put_contents('download.txt', $hit_count);
    }
    
    header('Location: file/xxx.zip');
    

    偶尔还是会失败,但至少不会截断你的计数器。

    【讨论】:

      【解决方案3】:

      在这种情况下,使用数据库记录访问(这将允许更多的数据挖掘,因为它可以按日期、时间、引荐来源、位置等进行趋势分析)将是比使用计数器更好的解决方案在一个平面文件中。

      一个原因可能是您在文件上的读取和写入操作之间发生冲突(每 8,000 个实例左右发生一次)。将 LOCK_EX 标志添加到 file_get_contents() PHP Reference 操作可能会阻止这种情况,但我不能 100% 确定。

      最好考虑将数据记录到数据库中,因为这几乎可以肯定可以防止您当前的计数丢失问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-26
        • 2010-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多