Php在写入时锁定文件

时间:2014-11-27 13:37:56

标签: php fwrite flock

我正在使用txt文件中的小数据库测试我的代码。我发现的最重要的问题是:当用户同时写入一个文件时。要解决这个问题,我使用的是flock。 我的计算机的操作系统是安装了xampp的Windows(评论这是因为我理解flocks在linux没有windows上工作正常)但是我需要在linux服务器上做这个测试。

实际上我已经通过在20个窗口中同时加载相同的脚本来测试我的代码。第一次结果工作正常,但测试数据库文件显示为空。

我的代码:

$file_db=file("test.db");
$fd=fopen("".$db_name."","w");

if (flock($fd, LOCK_EX)) 
    { 
    ftruncate($fd,0); 
    for ($i=0;$i<sizeof($file_db);$i++)
        {
        fputs($fd,"$file_db[$i]"."\n");
        }
    fflush($fd); 
    flock($fd, LOCK_UN);
    fclose($fd);
    }
else
    {
    print "Db Busy";
    }

脚本如何删除数据库文件内容。什么是正确的方法:使用flock修复现有代码或使用flock的其他替代技术?

2 个答案:

答案 0 :(得分:0)

我使用@ lolka_bolka的答案重新编写了脚本并且它有效。因此,在回答您的问题时,如果文件$db_name为空,则文件test.db可能为空。

答案 1 :(得分:0)

ftruncate之后的{p> fopen&#34; w&#34;是没用的。

file功能

  

返回数组中的文件。数组的每个元素对应于文件中的一行,换行符仍然附加。失败时,file()返回FALSE。

您不必添加额外的行尾符号。

flock功能

  

PHP支持一种以咨询方式锁定完整文件的可移植方式(这意味着所有访问程序必须使用相同的锁定方式,否则将无效)。

这意味着file函数不受锁影响。这意味着$file_db=file("test.db");可以在ftruncate($fd,0);fflush($fd);之间的某个位置读取文件。因此,您需要在锁定内部读取文件内容。

$db_name = "file.db";
$fd = fopen($db_name, "r+"); // w changed to r+ for getting file resource but not truncate it

if (flock($fd, LOCK_EX))
    {
    $file_db = file($db_name); // read file contents while lock obtained
    ftruncate($fd, 0);
    for ($i = 0; $i < sizeof($file_db); $i++)
        {
        fputs($fd, "$file_db[$i]");
        }
    fflush($fd);
    flock($fd, LOCK_UN);
    }
else
    {
    print "Db Busy";
    }
fclose($fd); // fclose should be called anyway

P.S。您可以使用控制台

测试此脚本
$  for i in {1..20}; do php 'file.php' >> file.log 2>&1 & done