文件锁定在PHP中

Rob*_*ank 7 php locking

我有一个新手(隔壁的少年)写了一些PHP代码来跟踪我的网站上的一些用法.我不熟悉php,所以我要问一些关于并发文件访问的问题.

我的原生应用程序(在Windows上)偶尔通过点击包含我的PHP脚本的URL将一些数据记录到我的网站.本机应用程序不检查返回的数据.

        $fh = fopen($updateFile, 'a') or die("can't open file");
        fwrite($fh, $ip);
        fwrite($fh, ', ');
        fwrite($fh, $date);
        fwrite($fh, ', ');
        fwrite($fh, implode(', ', $_GET));
        fwrite($fh, "\r\n");
        fclose($fh);
Run Code Online (Sandbox Code Playgroud)

这是一个流量较低的站点,数据并不重要.但是如果两个用户发生冲突并且脚本的两个实例都试图在文件中添加一行,会发生什么?在php中是否有任何隐式文件锁定?

上面的代码至少是安全的,不会锁定并且永远不会将控制权返回给我的用户吗?该文件可以被破坏吗?如果我上面的脚本每月删除文件,如果脚本的另一个实例正在写入文件,会发生什么?

Rho*_*Rho 12

你应该锁定文件:

<?php
$fp = fopen($updateFile, 'w+');
if(flock($fp, LOCK_EX)) {
fwrite($fp, 'a');
flock($fp, LOCK_UN);
} else {
echo 'can\'t lock';
}

fclose($fp);
Run Code Online (Sandbox Code Playgroud)

  • 是的,你需要在代码中使用`| LOCK_NB`,否则如果它已被锁定,锁就会锁定:) (4认同)
  • 正是我要找的,雷蒙德。谢谢。从我刚刚完成的其他阅读(http://www.tuxradar.com/practicalphp/8/11/0)来看,似乎永远无法达到回声语句。在文件被第一个进程解锁之前,第二个进程不会阻塞 flock 调用吗?羊群不需要 OR LOCK_NB 以便可以到达 echo 语句吗? (2认同)

mag*_*nes 6

为了记录,我在一个图书馆工作过:

https://github.com/EFTEC/DocumentStoreOne

它允许通过锁定文件来 CRUD 文件。我尝试了 100 个并发用户(同时调用了 100 个 PHP 脚本)并且它工作正常。

但是,它不使用 flock 而是使用 mkdir:

while (!@mkdir("file.lock")) {
   // use the file
   fopen("file"...)
   @rmdir("file.lock")
}
Run Code Online (Sandbox Code Playgroud)

为什么?

  1. mkdir 是原子的,所以锁是原子的:在一个步骤中,您锁定或不锁定。
  2. 它比flock(). 显然 flock 需要多次调用文件系统。
  3. flock() 取决于系统。
  4. 我做了一个压力测试,它奏效了。

  • 这有更多详细信息https://docstore.mik.ua/orelly/webprog/pcook/ch18_25.htm (2认同)