SafeStream: acceso seguro a archivos

Nette SafeStream garantiza que cada lectura y escritura en un archivo se realice de forma aislada. Esto significa que ningún hilo comenzará a leer un archivo que aún no se ha escrito por completo, o que varios hilos no sobrescribirán el mismo archivo.

Instalación:

composer require nette/safe-stream

¿Para qué sirve?

¿Para qué sirven realmente las operaciones aisladas? Comencemos con un ejemplo simple que escribe repetidamente en un archivo y luego lee la misma cadena de él:

$s = str_repeat('Long String', 10000);

$counter = 1000;
while ($counter--) {
	file_put_contents('soubor', $s); // escríbelo
	$readed = file_get_contents('soubor'); // léelo
	if ($s !== $readed) { // verifícalo
		echo '¡las cadenas difieren!';
	}
}

Puede parecer que la llamada echo '¡las cadenas difieren!' nunca puede ocurrir. Lo contrario es cierto. Intente ejecutar este script en dos pestañas del navegador al mismo tiempo. El error ocurrirá prácticamente de inmediato.

Una de las pestañas leerá el archivo en un momento en que la otra aún no lo haya escrito por completo, por lo que el contenido no estará completo.

Por lo tanto, el código proporcionado no es seguro si se ejecuta varias veces al mismo tiempo (es decir, en varios hilos). Lo cual no es nada inusual en Internet, a menudo un servidor responde a un gran número de usuarios al mismo tiempo. Por lo tanto, asegurarse de que su aplicación funcione de manera confiable incluso cuando se ejecuta en varios hilos (thread-safe) es muy importante. De lo contrario, se producirá una pérdida de datos y errores difíciles de detectar.

Pero como puede ver, las funciones nativas de PHP para leer y escribir archivos no son aisladas ni atómicas.

¿Cómo usar SafeStream?

SafeStream crea un protocolo seguro mediante el cual se pueden leer y escribir archivos de forma aislada utilizando funciones estándar de PHP. Simplemente agregue nette.safe:// antes del nombre del archivo:

file_put_contents('nette.safe://soubor', $s);
$s = file_get_contents('nette.safe://soubor');

SafeStream garantiza que como máximo un hilo pueda escribir en el archivo a la vez. Los otros hilos esperan en la cola. Si ningún hilo está escribiendo, cualquier número de hilos puede leer el archivo en paralelo.

Se pueden usar todas las funciones PHP comunes con el protocolo, por ejemplo:

// 'r' significa abrir solo para lectura
$handle = fopen('nette.safe://file.txt', 'r');

$ini = parse_ini_file('nette.safe://translations.neon');
versión: 3.0