【问题标题】:PHP Simultaneous File WritesPHP 同时写入文件
【发布时间】:2010-11-15 15:10:17
【问题描述】:

我有两个不同的 PHP 文件,它们都写入同一个文件。每个 PHP 脚本由两个不同 HTML 页面的用户操作调用。我知道可以调用两个 PHP 文件,但是两个 PHP 文件会同时尝试写入文件吗?如果是,会发生什么?此外,可以使其中一个 PHP 正常失败(文件写入将失败,而另一个 PHP 可以写入文件),因为一个 PHP 函数不如另一个函数重要。

【问题讨论】:

    标签: php file file-io


    【解决方案1】:

    解决这个问题的常用方法是让两个脚本都使用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);
    

    这样如果它发现某个文件正忙于处理文件,它就不会做任何事情。

    【讨论】:

      【解决方案2】:

      如果文件以追加方式打开,请注意 posix 声明原子访问。这意味着您可以使用多个线程附加到文件中,并且它们的行不会被损坏。

      我确实用十几个线程和几十万行对此进行了测试。没有一行被损坏。

      这可能不适用于超过 1kB 的字符串,因为缓冲区大小可能会超出。

      这也可能不适用于不符合 posix 的 Windows。

      【讨论】:

        【解决方案3】:

        请注意:

        从 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() 不再这样做了。

        【讨论】:

          【解决方案4】:

          看看flock函数。

          【讨论】:

            【解决方案5】:

            仅供参考:flock 仅适用于 *nix,不适用于 Windows

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-05-04
              • 2011-09-02
              • 2015-01-26
              • 1970-01-01
              • 2021-02-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多