2012-02-01 18 views
35

estoy tratando de crear una función (a los efectos de la tala)Atómicamente añadiendo una línea en un archivo y creándolo si no existe

append($path, $data) 

que

  1. crea un archivo $ si no existe y
  2. adjunta atómicamente $ datos.

Tiene que

  • soporte de alta concurrencia,
  • de apoyo cadenas largas y
  • ser tan performante como sea posible.

Hasta ahora el mejor intento es:

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

Funciona bien, pero parece que hay una bastante complejo. ¿Hay una manera más limpia (¿incorporada?) Para hacerlo?

Respuesta

75

PHP ya tiene una función incorporada para hacer esto, file_put_contents(). La sintaxis es la siguiente:

file_put_contents($filename, $data, FILE_APPEND); 

Tenga en cuenta que file_put_contents() va a crear el archivo si no existe ya (siempre y cuando tenga los permisos del sistema de archivos para hacerlo).

+0

¿Puedo preguntar para qué era el downvote? – FtDRbwLXw6

+3

Creo que esto no usará el modo 'x' para abrir un archivo (O_EXCL en C-land), por lo que puede tener una condición de carrera si no existe un archivo. Consulte https://github.com/php/php-src/blob/master/ext/standard/file.c (parece que solo usa 'c') –

+9

30 ups y no es la mejor respuesta. mundo pobre! ': (' –

57

usando la función interna de PHP http://php.net/manual/en/function.file-put-contents.php

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

FILE_APPEND => bandera de añadir el contenido al final del archivo

LOCK_EX => bandera para evitar que otra persona escribir en el archivo al mismo tiempo, (Disponible desde PHP 5.1)

Cuestiones relacionadas