2012-02-01 36 views
35

Tôi đang cố gắng để tạo ra một chức năng (cho mục đích khai thác gỗ)nguyên tử phụ thêm một dòng vào một tập tin và tạo ra nó nếu nó không tồn tại

append($path, $data) 

rằng

  1. tạo $ file nếu nó không tồn tại và
  2. gắn thêm dữ liệu vào dữ liệu đó một cách nguyên tử.

Nó phải

  • hỗ trợ đồng thời cao, chuỗi dài
  • hỗ trợ và
  • như performant càng tốt.

Cho đến nay các nỗ lực tốt nhất là:

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

Nó hoạt động OK, nhưng nó có vẻ là một khá phức tạp. Có cách dọn dẹp (tích hợp sẵn hơn) không?

Trả lời

75

PHP đã có chức năng tích hợp để thực hiện việc này, file_put_contents(). Cú pháp là:

file_put_contents($filename, $data, FILE_APPEND); 

Lưu ý rằng file_put_contents() sẽ tạo ra các tập tin nếu nó chưa tồn tại (miễn là bạn có quyền hệ thống tập tin để làm như vậy).

+0

Tôi có thể hỏi ý kiến ​​của bài viết này không? – FtDRbwLXw6

+3

Tôi tin rằng điều này sẽ không sử dụng chế độ 'x' để mở tệp (O_EXCL trong C-land), vì vậy bạn có thể có điều kiện chủng tộc nếu tệp không tồn tại. Xem https://github.com/php/php-src/blob/master/ext/standard/file.c (có vẻ như nó chỉ sử dụng 'c') –

+9

30 không phải là câu trả lời hay nhất. thế giới nghèo! ': (' –

57

sử dụng chức năng nội bộ của PHP http://php.net/manual/en/function.file-put-contents.php

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

FILE_APPEND => cờ để thêm nội dung vào cuối của tập tin

LOCK_EX => cờ để ngăn chặn bất cứ ai khác bằng văn bản cho các tập tin cùng một lúc (Có sẵn từ PHP 5.1)

Các vấn đề liên quan