SafeStream: Sicurezza per i file

Nette SafeStream garantisce che ogni lettura e scrittura di un file sia isolata. Ciò significa che nessun thread inizierà a leggere un file che non è ancora stato completamente scritto, o che più thread non sovrascriveranno lo stesso file.

Installazione:

composer require nette/safe-stream

A cosa serve?

A cosa servono le operazioni isolate? Cominciamo con un semplice esempio che scrive ripetutamente su un file e poi legge la stessa stringa da esso:

$s = str_repeat('Stringa lunga', 10000);

$counter = 1000;
while ($counter--) {
	file_put_contents('file', $s); // scriverlo
	$readed = file_get_contents('file'); // leggerlo
	if ($s !== $readed) { // verifica
		echo "Le stringhe sono diverse!";
	}
}

Potrebbe sembrare che echo 'strings differ!' non possa mai verificarsi. È vero il contrario. Provate a eseguire questo script in due schede del browser contemporaneamente. L'errore si verificherà quasi immediatamente.

Una delle schede leggerà il file in un momento in cui l'altra non ha avuto la possibilità di scriverlo tutto, quindi il contenuto non sarà completo.

Pertanto, il codice non è sicuro se viene eseguito più volte contemporaneamente (cioè in più thread). Questo non è raro in Internet, dove spesso un server risponde a un gran numero di utenti contemporaneamente. Pertanto, è molto importante garantire che l'applicazione funzioni in modo affidabile anche quando viene eseguita in più thread (thread-safe). In caso contrario, i dati andranno persi e si verificheranno errori difficili da individuare.

Ma come si può vedere, le funzioni native di lettura e scrittura dei file di PHP non sono isolate e atomiche.

Come usare SafeStream?

SafeStream crea un protocollo sicuro per leggere e scrivere file in isolamento, utilizzando funzioni PHP standard. Tutto ciò che occorre fare è specificare nette.safe:// prima del nome del file:

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

SafeStream assicura che solo un thread alla volta possa scrivere sul file. Gli altri thread sono in attesa nella coda. Se nessun thread sta scrivendo, qualsiasi numero di thread può leggere il file in parallelo.

Tutte le funzioni PHP comuni possono essere utilizzate con il protocollo, ad esempio:

// 'r' significa aprire in sola lettura
$handle = fopen('nette.safe://file.txt', 'r');

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