文件锁定在PHP中

时间:2011-03-27 13:06:16

标签: 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);

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

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

3 个答案:

答案 0 :(得分: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);

答案 1 :(得分:3)

由于这是对文件的附加,最好的方法是聚合数据并将其写入一个fwrite()中的文件,前提是要写入的数据不大于文件缓冲区。当然你并不总是知道缓冲区的大小,所以flock();总是一个不错的选择。

答案 2 :(得分:1)

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

https://github.com/EFTEC/DocumentStoreOne

它允许通过锁定文件来CRUD文件。我尝试了100个并发用户(同时有100个对PHP的调用),它仍然有效。

但是,它不使用flock而是mkdir

while (!@mkdir("file.lock")) {
   // use the file
   fopen("file"...)
   @rmdir("file.lock")
}

为什么?

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