繁体   English   中英

php中的文件锁定

[英]file locking in php

我让一个新人(隔壁的少年)编写了一些 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中是否有任何隐式文件锁定?

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

您应该锁定文件:

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

fclose($fp);

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

https://github.com/EFTEC/DocumentStoreOne

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

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

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

为什么?

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM