以原子方式将一行添加到文件中,如果该文件不存在则创建该文件

Jak*_*čar 35 php

我正在尝试创建一个函数(用于记录)

append($path, $data)
Run Code Online (Sandbox Code Playgroud)

  1. 如果不存在则创建$ file
  2. 原子地将$ data附加到它.

它必须

  • 支持高并发性,
  • 支持长串和
  • 尽可能高效.

到目前为止,最好的尝试是:

function append($file, $data)
{
    // Ensure $file exists. Just opening it with 'w' or 'a' might cause
    // 1 process to clobber another's.
    $fp = @fopen($file, 'x');
    if ($fp)
        fclose($fp);

    // Append
    $lock = strlen($data) > 4096; // assume PIPE_BUF is 4096 (Linux)

    $fp = fopen($file, 'a');
    if ($lock && !flock($fp, LOCK_EX))
        throw new Exception('Cannot lock file: '.$file);
    fwrite($fp, $data);
    if ($lock)
        flock($fp, LOCK_UN);
    fclose($fp);
}
Run Code Online (Sandbox Code Playgroud)

它工作正常,但似乎相当复杂.是否有更清洁(内置?)的方式来做到这一点?

FtD*_*Xw6 76

PHP已经有一个内置函数来执行此操作,即file_put_contents().语法是:

file_put_contents($filename, $data, FILE_APPEND);
Run Code Online (Sandbox Code Playgroud)

请注意,file_put_contents()如果文件尚不存在,则会创建该文件(只要您具有文件系统权限).

  • 30上升而不是最好的答案.穷人的世界!`(` (11认同)
  • 我相信这不会使用模式'x'来打开文件(C-land中的O_EXCL),因此如果文件不存在,你可能会遇到竞争条件.请参阅https://github.com/php/php-src/blob/master/ext/standard/file.c(看起来它只是使用'c') (3认同)

cat*_*int 59

使用PHP的内部函数http://php.net/manual/en/function.file-put-contents.php

file_put_contents($file, $data, FILE_APPEND | LOCK_EX);
Run Code Online (Sandbox Code Playgroud)

FILE_APPEND =>标志将内容附加到文件末尾

LOCK_EX =>标志,以防止其他人同时写入该文件(自PHP 5.1起可用)