我有一个我想要执行的php脚本,只有当脚本的其他实例尚未运行时才会执行。我有这个代码:
$lockfile = __DIR__.'/lock.file';
if(file_exists($lockfile) == false)
{
echo 'no lockfile. Job will execute.';
$handle = fopen($lockfile, 'x') or die('Cannot open file: '.$lockfile);
$data = 'This is the lockfile';
fwrite($handle, $data);
fclose($lockfile);
createLinks();
unlink($lockfile);
}
else
{
echo 'Lockfile present, job will not execute. Please try again later';
}
但是它没有正确检查文件是否存在。如果我用浏览器调用脚本,则会正确创建lock.file(我可以用ftp查看),然后删除。但是,我仍然可以同时多次运行脚本。如果我自己用ftp创建一个lock.file,它就不会执行脚本。我现在一直在寻找几个小时,它能成为什么?也许我很蠢,但我认为这应该有用,对吗?
编辑: Jep,flock做到了。非常感谢!最终代码:
$lockfile = __DIR__.'/lock.file';
$handle = fopen($lockfile, "x");
if(flock($handle, LOCK_EX))
{
echo 'no lockfile. Job will execute.';
$data = 'This is the lockfile';
fwrite($handle, $data);
createLinks();
fclose($lockfile);
unlink($lockfile);
}
else
{
echo 'Lockfile present, job will not execute. Please try again later';
}
答案 0 :(得分:4)
来自file_exists
的文档:
注意:缓存此函数的结果。有关详细信息,请参阅clearstatcache()。
和
您还应注意PHP不会缓存有关不存在文件的信息。因此,如果在不存在的文件上调用file_exists(),则在创建文件之前它将返回FALSE。如果您创建该文件,即使您删除该文件,它也将返回TRUE。但是unlink()会自动清除缓存
尝试将您的功能更改为:
if(file_exists($lockfile) == false)
{
clearstatcache();
...
答案 1 :(得分:1)
我今天在半天的时间内处理与你的问题几乎相同的问题。我的PHP代码也使用了文件锁,并在其中调用了file_exists()。我对“奇怪的”file_exists()结果遇到了同样的问题。当我将文件的使用(获得锁定)更改为数据库的使用时 - 我完全感到困惑 - 一个锁对应于表中的一行。结果完全相同 - 我试图在浏览器的不同选项卡中同时启动代码,但我仍然无法获得锁定。
然后我意识到这种奇怪行为的真正原因是什么。在我的情况下(看起来你的情况是相同的)主要问题在于脚本是“多次同时”启动但在一个浏览器中。但请求不是同时处理,而是顺序处理。这里给出了这种效果的一个很好的解释: https://stackoverflow.com/a/3623584/1758680
因为所有请求都按顺序进行 - 每个请求都在等待前一个请求结束。每个锁都在下一个脚本启动之前被释放并尝试获得锁定。
答案 2 :(得分:-1)
尝试
$lockfile = 'lock.file';
或其他..