SafeStream: biztonságosan a fájlokhoz
A Nette SafeStream garantálja, hogy minden fájlolvasás és -írás izoláltan történik. Ez azt jelenti, hogy egyetlen szál sem kezd el olvasni egy olyan fájlt, amely még nincs teljesen megírva, vagy több szál nem írja felül ugyanazt a fájlt.
Telepítés:
composer require nette/safe-stream
Mire jó ez?
Mire jók valójában az izolált műveletek? Kezdjük egy egyszerű példával, amely ismételten ír egy fájlba, majd ugyanazt a stringet olvassa ki belőle:
$s = str_repeat('Hosszú String', 10000);
$counter = 1000;
while ($counter--) {
file_put_contents('fajl', $s); // írja be
$readed = file_get_contents('fajl'); // olvassa ki
if ($s !== $readed) { // ellenőrizze
echo 'a stringek különböznek!';
}
}
Úgy tűnhet, hogy az echo 'a stringek különböznek!'
hívás soha nem fordulhat elő. Az ellenkezője igaz.
Próbálja meg ezt a szkriptet egyszerre két böngészőfülön futtatni. A hiba gyakorlatilag azonnal bekövetkezik.
Az egyik fül ugyanis akkor olvassa be a fájlt, amikor a másik még nem fejezte be teljesen az írást, így a tartalom nem lesz teljes.
A megadott kód tehát nem biztonságos, ha egyszerre többször hajtják végre (azaz több szálon). Ami az interneten nem szokatlan, gyakran egy időben válaszol a szerver nagyszámú felhasználónak. Tehát annak biztosítása, hogy az alkalmazása megbízhatóan működjön több szálon történő végrehajtás esetén is (thread-safe), nagyon fontos. Ellenkező esetben adatvesztés és nehezen felderíthető hibák keletkeznek.
Ahogy azonban láthatja, a natív PHP fájlolvasási és -írási függvények nem izoláltak és atomiak.
Hogyan használjuk a SafeStream-et?
A SafeStream létrehoz egy biztonságos protokollt, amellyel izoláltan lehet olvasni és írni fájlokat a standard PHP
függvények segítségével. Csak annyit kell tenni, hogy a nette.safe://
előtagot kell a fájlnév
elé írni:
file_put_contents('nette.safe://fajl', $s);
$s = file_get_contents('nette.safe://fajl');
A SafeStream biztosítja, hogy egyszerre legfeljebb egy szál írhat a fájlba. A többi szál sorban várakozik. Ha egyetlen szál sem ír, akkor tetszőleges számú szál olvashatja párhuzamosan a fájlt.
A protokollal minden szokásos PHP függvény használható, például:
// 'r' azt jelenti, hogy csak olvasásra nyissa meg
$handle = fopen('nette.safe://file.txt', 'r');
$ini = parse_ini_file('nette.safe://translations.neon');