SafeStream: acces securizat la fișiere
Nette SafeStream garantează că fiecare citire și scriere într-un fișier se desfășoară izolat. Aceasta înseamnă că niciun fir de execuție nu va începe să citească un fișier care nu este încă complet scris, sau mai multe fire de execuție nu vor suprascrie același fișier.
Instalare:
composer require nette/safe-stream
La ce este bun?
La ce sunt bune operațiile izolate, de fapt? Să începem cu un exemplu simplu care scrie în mod repetat într-un fișier și apoi citește același șir din el:
$s = str_repeat('Long String', 10000);
$counter = 1000;
while ($counter--) {
file_put_contents('fisier', $s); // scrie-l
$readed = file_get_contents('fisier'); // citește-l
if ($s !== $readed) { // verifică-l
echo 'șirurile diferă!';
}
}
Poate părea că apelul echo 'șirurile diferă!'
nu poate avea loc niciodată. Opusul este adevărat. Încercați
să rulați acest script în două tab-uri de browser simultan. Eroarea va apărea practic imediat.
Unul dintre tab-uri va citi fișierul într-un moment în care celălalt nu a reușit încă să îl scrie complet, astfel încât conținutul nu va fi complet.
Codul menționat nu este deci sigur dacă se execută de mai multe ori în același timp (adică în mai multe fire de execuție). Ceea ce pe internet nu este nimic neobișnuit, adesea serverul răspunde unui număr mare de utilizatori în același timp. Deci, asigurarea că aplicația dvs. funcționează fiabil chiar și atunci când este executată în mai multe fire de execuție (thread-safe) este foarte importantă. Altfel, se va ajunge la pierderea datelor și la apariția unor erori greu de detectat.
Dar, după cum puteți vedea, funcțiile native PHP pentru citirea și scrierea fișierelor nu sunt izolate și atomice.
Cum se utilizează SafeStream?
SafeStream creează un protocol sigur prin care se pot citi și scrie fișiere în mod izolat, folosind funcțiile standard
PHP. Este suficient să prefixați numele fișierului cu nette.safe://
:
file_put_contents('nette.safe://fisier', $s);
$s = file_get_contents('nette.safe://fisier');
SafeStream asigură că, la un moment dat, maxim un fir de execuție poate scrie în fișier. Celelalte fire de execuție așteaptă la coadă. Dacă niciun fir de execuție nu scrie, fișierul poate fi citit în paralel de orice număr de fire de execuție.
Cu protocolul se pot utiliza toate funcțiile PHP obișnuite, de exemplu:
// 'r' înseamnă deschidere doar pentru citire
$handle = fopen('nette.safe://file.txt', 'r');
$ini = parse_ini_file('nette.safe://translations.neon');