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


Atomically appending a line to a file and creating it if it doesn't exist

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

append($file, $data)

  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);
}

它工作正常,但它似乎相当复杂。有没有更清洁(内置?(的方法可以做到这一点?

PHP 已经有一个内置函数来执行此操作,file_put_contents((。 语法为:

file_put_contents($filename, $data, FILE_APPEND);

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

(。

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

file_put_contents($file, $data, FILE_APPEND | LOCK_EX);

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

LOCK_EX => 标志以防止其他人同时写入文件(从 PHP 5.1 开始可用(