2011-03-27 35 views
5

Tenía un recién llegado (el adolescente de al lado) escribir un código php para rastrear el uso en mi sitio web. No estoy familiarizado con php, así que estoy preguntando un poco sobre el acceso a archivos concurrentes.bloqueo de archivos en php

Mi aplicación nativa (en Windows), ocasionalmente registra algunos datos en mi sitio al presionar la URL que contiene mi script php. La aplicación nativa no examina los datos devueltos.

 $fh = fopen($updateFile, 'a') or die("can't open file"); 
     fwrite($fh, $ip); 
     fwrite($fh, ', '); 
     fwrite($fh, $date); 
     fwrite($fh, ', '); 
     fwrite($fh, implode(', ', $_GET)); 
     fwrite($fh, "\r\n"); 
     fclose($fh); 

Este es un sitio de poco tráfico, y los datos no son críticos. Pero, ¿qué ocurre si dos usuarios colisionan y dos instancias del script intentan agregar una línea al archivo? ¿Hay algún bloqueo de archivo implícito en php?

¿El código de seguridad está bloqueado por lo menos y nunca devuelve el control a mi usuario? ¿Puede el archivo corromperse? Si tengo el script anterior, elimine el archivo cada mes, ¿qué sucede si otra instancia del script está en el medio de escribir en el archivo?

Respuesta

9

se debería poner un bloqueo en el archivo:

<?php 
$fp = fopen($updateFile, 'w+'); 
if(flock($fp, LOCK_EX)) { 
fwrite($fp, 'a'); 
flock($fp, LOCK_UN); 
} else { 
echo 'can\'t lock'; 
} 

fclose($fp); 
+0

Exactamente lo que estaba buscando, Raymond. Gracias. De otra lectura que acabo de hacer (http://www.tuxradar.com/practicalphp/8/11/0), parece que la declaración del eco podría no ser alcanzada. ¿No se bloqueará un segundo proceso en la llamada de bandada hasta que un primer proceso desbloquee el archivo? ¿El lote no necesita un OR LOCK_NB para poder alcanzar la declaración del eco? – RobertFrank

+0

Tenía la esperanza de obtener una respuesta del Sr. Ho u otra persona aquí en cuanto a si mi observación de que la declaración de eco anterior se alcanzaría o no. – RobertFrank

+4

Sí, necesita un '| LOCK_NB' en el código; de lo contrario, el bloqueo se bloquearía si ya estuviera bloqueado :) – cweiske

3

Dado que este es un anexados para el archivo, la mejor forma sería la de agregar los datos y escribir en el archivo en una fwrite(), proporcionar los datos que se escribirán no es más grande que el búfer de archivos. Por supuesto, no siempre se sabe el tamaño del buffer, así que flock(); siempre es una buena opción.

+0

Haría ambas cosas: mantener la escritura en un solo 'fwrite()' * y * bloquear el archivo. En algunas plataformas Linux y en algunos sistemas de archivos antiguos, 'flock()' puede que no bloquee el archivo. – Jason