我正在使用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
的其他替代技术?
答案 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