文件锁定在PHP中

问题描述 投票:6回答:3

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

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

php locking
3个回答
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);

3
投票

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


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. flock取决于系统。
  4. 我做了压力测试,但它确实奏效了。
© www.soinside.com 2019 - 2024. All rights reserved.