我正在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需要它是健壮的还是原子的,我只是希望它失败。)
我已经看到很多关于这个主题的其他问题,但它们似乎都与访问同一文件的多个脚本有关,这不是这里的情况。
答案 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);
}