0

我写了这个计数器来跟踪网站的是/否,它工作得很好,问题是文件在写作时搞砸了。例如:它将从 126 变为 27。脚本是从我编写的 iOS 应用程序调用的,因此很可能有多个连接同时修改文件,我认为这就是导致问题的原因。我并不是一个真正的 PHP 人,所以我希望对什么可以使代码更好一点并处理多个同时连接有所了解。

<?php

        $yes_file = 'yes.txt';
        $no_file  = 'no.txt';

        $yes_count = file_get_contents($yes_file);
        $no_count = file_get_contents($no_file);

        if ($_GET['result'])
        {
                if( strcmp($_GET['result'], "YES") ) {
                        $no_count+=1;
                        file_put_contents($no_file, $no_count);
                }
                else {
                        $yes_count+=1;
                        file_put_contents($yes_file, $yes_count);
                }
        }

        $total = $yes_count + $no_count;
        echo "{\"yescount\":" . $yes_count.",";
        echo "\"nocount\":" . $no_count.",";
        echo "\"total\":" . $total."}";

?>

谢谢!

4

2 回答 2

1

这应该更有效率。

仅供参考,数据库在递增时在行/表上放置写锁,这与我在下面所做的相同,因此数据库不是解决方案 - 解决方案是写锁(通过数据库或通过 PHP) . 你可以使用flock,但我觉得那很乱,所以我只用一个临时文件完成了它。

我的代码在这里的唯一问题是,如果服务器在这个脚本中间崩溃,那么写锁将保持原位(MySQL 有时也有这个问题)。我通常通过time()在文件中写入并检查它是否不超过一个小时或什么来解决这个问题。但在你的情况下,这可能是不必要的。

<?php

// Your variables
$yes_file = 'yes.txt';
$no_file  = 'no.txt';

if (isset($_GET['result']))
{
// Write lock
while(file_exists('temporaryfile')) usleep(100000);
file_put_contents('temporaryfile','1');

$yes_count = (int)file_get_contents($yes_file);
$no_count = (int)file_get_contents($no_file);

// Increment
if ($_GET['result']=='YES')
    {
    $yes_count++;
    file_put_contents($yes_file, $yes_count);
    }
else
    {
    $no_count++;
    file_put_contents($no_file, $no_count);
    }

// Unlock
unlink('temporaryfile');
}
else // No need for any lock so just get the vars
{
$yes_count = (int)file_get_contents($yes_file);
$no_count = (int)file_get_contents($no_file);
}

$total = $yes_count + $no_count;
echo "{\"yescount\":$yes_count,\n\"nocount\":$no_count,\n\"total\":$total}";
于 2013-05-28T02:27:26.967 回答
1

首先,我建议使用数据库系统来跟踪计数器。

关于您的问题,在读取-更新-写入周期中对文件进行flock()会有所帮助。这可以防止竞争条件

于 2013-05-27T21:57:48.347 回答