2012-02-01 6 views
35

Próbuję utworzyć funkcję (w celach logowania)atomowo dołączanie linię do pliku i tworzenie go, jeśli nie istnieje

append($path, $data) 

że

  1. tworzy $ file jeśli nie istnieje i atomically dołącza do niego dane $.

Musi

  • wsparcia wysokiej współbieżności,
  • wsparcia długich ciągów i
  • być tak wydajnych jak to możliwe.

Dotychczas najlepszy próba jest:

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

To działa OK, ale wydaje się być dość skomplikowane. Czy istnieje sposób czyszczenia (wbudowany?), Aby to zrobić?

Odpowiedz

75

PHP ma już wbudowaną funkcję do wykonania tego, file_put_contents(). Składnia jest następująca:

file_put_contents($filename, $data, FILE_APPEND); 

Zauważ, że file_put_contents() utworzy plik, jeśli nie istnieje (tak długo, jak masz uprawnienia systemu plików, aby to zrobić).

+0

Czy mogę zapytać, o co chodzi? – FtDRbwLXw6

+3

Wierzę, że to nie będzie używało trybu "x" do otwierania pliku (O_EXCL w C-land), więc możesz mieć warunki wyścigu, jeśli plik nie istnieje. Zobacz https://github.com/php/php-src/blob/master/ext/standard/file.c (wygląda na to, że po prostu używa "c") –

+9

30 ups i nie jest najlepszą odpowiedzią. biedny świat! ': (' –

57

użyciem funkcji wewnętrznego PHP http://php.net/manual/en/function.file-put-contents.php

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

FILE_APPEND => flag do dołączania zawartości do końca pliku

flag LOCK_EX =>, aby uniemożliwić innym osobom na zapisywanie do pliku w tym samym czasie (Dostępne od PHP 5.1)

Powiązane problemy