Windows与Linux上的PHP flock()行为差异

时间:2015-09-12 03:02:30

标签: php linux windows

我正在Windows机器和Linux机器上执行相同的代码段。两者都运行PHP 5.4:

$file = "lock.txt";
$fp = fopen($file, "w+");
flock($fp, LOCK_EX);
var_dump(@file_put_contents($file, 'hello' . rand()));
flock($fp, LOCK_UN);
fclose($fp);

在Windows计算机上,file_put_contents()操作失败并返回false。在Linux机器上,它成功了。

我试图找出这两种行为中的哪一种实际上是正确的,以及如何在两个系统中标准化行为(为了记录,我的目标是让file_put_contents()失败。我不知道#39; t需要它是健壮的还是原子的,我只是希望它失败。)

我已经看到很多关于这个主题的其他问题,但它们似乎都与访问同一文件的多个脚本有关,这不是这里的情况。

2 个答案:

答案 0 :(得分:2)

flock()的文档似乎确实回答了这个问题,尽管没有尽可能完整。文档 状态

  

flock()在Windows上使用强制锁定而不是建议锁定

这很清楚,但我被first comment读取了

  

Flock仅使用ADVISORY锁定;也就是说,其他流程可能   完全忽略锁定

我正在解释这意味着我自己的过程会隐含地尊重锁;实际上它似乎意味着类似的东西,"我们假设 - 一旦你首先使用flock() - 你会记得在任何写入之前检查锁的状态,但请记住,其他程序可能没有这样做。"

答案 1 :(得分:0)

在使用 fopen() 打开文件并使用 flock() 锁定文件后,我使用 SimpleXMLElement:asXML() 将 XML 写入文件的经验相同,为 Windows 10 编写 PHP。该文件将在Windows 机器,虽然它在我的 Linux 机器上工作得很好,并且会将文件与 XML 文档一起保留。我会尝试在 Windows 机器上有一个单独的“锁定文件”,打开它进行读取以获取文件描述符,然后使用排他或共享锁锁定它,然后使用您的 PHP file_get_contents(), asXML(), simpleXML_load_file (),无论实际文件的情况如何,然后使用 flock() 解锁锁定文件并使用 fclose() 关闭它。我猜这效果更好,因为使用 fopen() 打开文件进行写入似乎会干扰 Windows 上的这些 PHP 函数。

所以,你会...

   $fd=fopen("lockfile.txt", "r");
   flock($fd, LOCK_EX);
   $text=file_get_contents("myFile");
   $text .= "Add some text.\n";
   file_put_contents("myFile", $text);
   flock($fd, LOCK_UN);
   fclose($fd);

   $fd=fopen("lockfile.txt", "r");
   flock($fd, LOCK_SH);
   $text = file_get_contents("myFile");
   echo $text;
   flock($fd, LOCK_UN);
   fclose($fd);

“锁定文件”只是作为一个交通灯来保护程序中重要的实际文件。在 Windows 中你需要这样做,因为理论上那些 PHP 函数不会对已经被 fopen() 打开的文件进行操作,而你仍然需要一个文件描述符作为 flock() 的参数。

确保“lockfile.txt”或任何您命名的文件存在!

   if (!file_exists("lockfile.txt")){
          $fd = fopen("lockfile.txt", "w");
          fwrite("lockfile.txt", "This lockfile now exists!\n");
          fclose($fd);
   }