file_exists似乎无法正常工作

时间:2013-03-03 18:20:44

标签: php file-permissions file-exists

我有一个我想要执行的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';
}

3 个答案:

答案 0 :(得分:4)

来自file_exists的文档:

  

注意:缓存此函数的结果。有关详细信息,请参阅clearstatcache()。

  

您还应注意PHP不会缓存有关不存在文件的信息。因此,如果在不存在的文件上调用file_exists(),则在创建文件之前它将返回FALSE。如果您创建该文件,即使您删除该文件,它也将返回TRUE。但是unlink()会自动清除缓存

尝试将您的功能更改为:

if(file_exists($lockfile) == false)
{
    clearstatcache();
    ...

查看clearstatcache()

答案 1 :(得分:1)

我今天在半天的时间内处理与你的问题几乎相同的问题。我的PHP代码也使用了文件锁,并在其中调用了file_exists()。我对“奇怪的”file_exists()结果遇到了同样的问题。当我将文件的使用(获得锁定)更改为数据库的使用时 - 我完全感到困惑 - 一个锁对应于表中的一行。结果完全相同 - 我试图在浏览器的不同选项卡中同时启动代码,但我仍然无法获得锁定。

然后我意识到这种奇怪行为的真正原因是什么。在我的情况下(看起来你的情况是相同的)主要问题在于脚本是“多次同时”启动但在一个浏览器中。但请求不是同时处理,而是顺序处理。这里给出了这种效果的一个很好的解释: https://stackoverflow.com/a/3623584/1758680

因为所有请求都按顺序进行 - 每个请求都在等待前一个请求结束。每个锁都在下一个脚本启动之前被释放并尝试获得锁定。

答案 2 :(得分:-1)

尝试

$lockfile = 'lock.file';

或其他..