我有两个不同的PHP文件都写入同一个文件。每个PHP脚本由两个不同HTML页面的用户操作调用。我知道可以调用两个PHP文件,但两个PHP文件是否会同时尝试写入文件?如果是的话,会发生什么?此外,可以使其中一个PHP正常失败(文件写入将失败,另一个PHP可以写入文件),因为一个PHP函数不如另一个重要。
答案 0 :(得分:31)
解决此问题的通常方法是让两个脚本都使用flock()
进行锁定:
$f = fopen('some_file', 'a');
flock($f, LOCK_EX);
fwrite($f, "some_line\n");
flock($f, LOCK_UN);
fclose($f);
这将导致脚本在写入之前等待彼此完成文件。如果您愿意,可以执行“不太重要”的脚本:
$f = fopen('some_file', 'a');
if(flock($f, LOCK_EX | LOCK_NB)) {
fwrite($f, "some_line\n");
flock($f, LOCK_UN);
}
fclose($f);
这样如果发现某些东西忙于文件,它就不会做任何事情。
答案 1 :(得分:11)
请注意,如果文件以追加打开,posix会声明原子访问。这意味着您可以只使用多个线程附加到该文件,并且它们的行不会被破坏。
我用十几个线程和几十万行测试了这个。没有一行被破坏。
这可能不适用于超过1kB的字符串,因为buffersize可能会超过。
这可能也不适用于不符合posix标准的Windows。
答案 2 :(得分:9)
请注意:
从PHP 5.3.2开始,删除了文件资源句柄关闭时的自动解锁。 现在解锁总是必须手动完成。
更新后向兼容代码为:
if (($fp = fopen('locked_file', 'ab')) !== FALSE) {
if (flock($fp, LOCK_EX) === TRUE) {
fwrite($fp, "Write something here\n");
flock($fp, LOCK_UN);
}
fclose($fp);
}
即。你必须明确地调用flock(..,LOCK_UN)因为fclose()不再这样做了。
答案 3 :(得分:1)
查看flock功能。
答案 4 :(得分:-4)
仅供参考:flock仅适用于* nix,在Windows上不可用