2008-11-16 25 views
10

Estoy construyendo una pequeña aplicación web en PHP que almacena cierta información en un archivo de texto sin formato. Sin embargo, todos los usuarios de mi aplicación utilizan/modifican este archivo de texto en un momento dado y posible al mismo tiempo.PHP y acceso simultáneo a archivos

Así que la pregunta es. ¿Cuál sería la mejor manera de asegurarse de que solo un usuario pueda realizar cambios en el archivo en cualquier momento dado?

Respuesta

19

Usted debe poner un bloqueo en el archivo

<?php 

$fp = fopen("/tmp/lock.txt", "w+"); 

if (flock($fp, LOCK_EX)) { // do an exclusive lock 
    fwrite($fp, "Write something here\n"); 
    flock($fp, LOCK_UN); // release the lock 
} else { 
    echo "Couldn't lock the file !"; 
} 

fclose($fp); 

?> 

Tome un vistazo a la http://www.php.net/flock

10

Mi sugerencia es usar SQLite. Es rápido, liviano, se almacena en un archivo y tiene mecanismos para evitar modificaciones simultáneas. A menos que se trate de un formato de archivo preexistente, SQLite es el camino a seguir.

2

Un archivo único para muchos usuarios realmente no debería ser la estrategia que utiliza No creo; de lo contrario, probablemente necesite implementar un único punto de acceso (global) que supervise si el archivo está siendo editado o no. Adquirir un bloqueo, hacer su modificación, liberar el bloqueo, etc. Me gustaría ir con 'Nadie sugiere utilizar una base de datos (SQLite si no quiere la sobrecarga de un RDBMS completamente decorado)

3

Podría hacer una commit log tipo de formato, más o menos como lo hace wikipedia.

Utilice una base de datos y cada cambio guardado crea una nueva fila en la base de datos que hace que el registro anterior sea redundante, con un valor incrementado, entonces solo tiene que preocuparse de obtener bloqueos de tabla durante la fase de guardado.

De esta forma, al menos si dos personas concurrentes editan algo, ambos cambios aparecerán en el historial y cualquiera que se haya perdido en la guerra de compromiso se puede copiar a la nueva revisión.

Ahora, si no quiere usar una base de datos, entonces tiene que preocuparse por tener un archivo de control de revisión que respalde cada archivo visible.

Se puede poner un control de revisión (GIT/mercurial/SVN) en el sistema de archivos y luego automatizar compromete durante la fase de guardar,

pseudocódigo:

user->save : 
    getWritelock(); 
    write($file); 
    write_commitmessage($commitmessagefile); # <-- author , comment, etc 
    call "hg commit -l $commitmessagefile $file " ; 
    releaseWriteLock(); 
done. 

Al menos de esta manera cuando 2 personas hacer commits críticos al mismo tiempo, ninguno se perderá.

Cuestiones relacionadas