SafeStream: accesso sicuro ai file
Nette SafeStream garantisce che ogni lettura e scrittura su file avvenga in modo isolato. Ciò significa che nessun thread inizierà a leggere un file che non è ancora stato scritto completamente, o più thread non sovrascriveranno lo stesso file.
Installazione:
composer require nette/safe-stream
A cosa serve?
A cosa servono effettivamente le operazioni isolate? Iniziamo con un semplice esempio che scrive ripetutamente su un file e successivamente legge la stessa stringa da esso:
$s = str_repeat('Long String', 10000);
$counter = 1000;
while ($counter--) {
file_put_contents('file', $s); // scrivilo
$readed = file_get_contents('file'); // leggilo
if ($s !== $readed) { // controllalo
echo 'le stringhe sono diverse!';
}
}
Potrebbe sembrare che la chiamata echo 'le stringhe sono diverse!'
non possa mai verificarsi. È vero il
contrario. Provate ad eseguire questo script in due schede del browser contemporaneamente. L'errore si verificherà praticamente
immediatamente.
Una delle schede leggerà infatti il file nel momento in cui l'altra non ha ancora finito di scriverlo completamente, quindi il contenuto non sarà completo.
Il codice fornito non è quindi sicuro se viene eseguito più volte contemporaneamente (cioè in più thread). Il che su Internet non è niente di insolito, spesso un server risponde a un gran numero di utenti contemporaneamente. Quindi assicurarsi che la tua applicazione funzioni in modo affidabile anche quando viene eseguita in più thread (thread-safe) è molto importante. Altrimenti si verificherà una perdita di dati e l'insorgere di errori difficili da individuare.
Come puoi vedere, però, le funzioni PHP native per la lettura e la scrittura di file non sono isolate e atomiche.
Come usare SafeStream?
SafeStream crea un protocollo sicuro tramite il quale è possibile leggere e scrivere file in modo isolato utilizzando le
funzioni PHP standard. Basta solo specificare nette.safe://
prima del nome del file:
file_put_contents('nette.safe://file', $s);
$s = file_get_contents('nette.safe://file');
SafeStream garantisce che al massimo un thread possa scrivere sul file contemporaneamente. Gli altri thread attendono in coda. Se nessun thread sta scrivendo, qualsiasi numero di thread può leggere il file parallelamente.
Con il protocollo è possibile utilizzare tutte le comuni funzioni PHP, ad esempio:
// 'r' significa aprire solo per la lettura
$handle = fopen('nette.safe://file.txt', 'r');
$ini = parse_ini_file('nette.safe://translations.neon');