SafeStream: Защита на файловете
Nette\Utils\SafeStream гарантира, че всяко четене и запис в даден файл е изолирано. Това означава, че никоя нишка няма да започне да чете файл, който все още не е напълно записан, или че няколко нишки ще презапишат един и същ файл.
Монтаж:
composer require nette/safe-stream
За какво е полезен?
Каква е действителната полезност на изолираните операции? Нека започнем с прост пример, който многократно записва във файл и след това прочита от него същия низ:
$s = str_repeat('Дълъг низ', 10000);
$counter = 1000;
while ($counter--) {
file_put_contents('file', $s); // пишем
$readed = file_get_contents('file'); // читаем
if ($s !== $readed) { // check it
echo 'низовете са различни!';
}
}
Може да изглежда, че echo 'strings differ!'
никога не може да се появи.
Обратното също е вярно. Опитайте да стартирате този скрипт в два
раздела на браузъра едновременно. Грешката ще се появи почти
веднага.
Единият от разделите ще прочете файла, докато другият все още не е имал време да запише всичко, така че съдържанието ще бъде непълно.
Следователно кодът не е безопасен, ако се изпълнява многократно едновременно (т.е. в няколко нишки). Това не е рядкост в интернет, тъй като често сървърът отговаря на голям брой потребители едновременно. Ето защо е много важно да се гарантира, че приложението работи надеждно дори когато се изпълнява в няколко нишки (thread-safe). В противен случай ще бъдат загубени данни и ще се появят трудно откриваеми грешки.
Но както виждате, вградените функции на PHP за четене и запис на файлове не са изолирани и атомарни.
Как да използвам SafeStream?
SafeStream създава защитен протокол за изолирано четене и писане на
файлове с помощта на стандартни функции на PHP. Всичко, което трябва да
направите, е да посочите nette.safe://
преди името на файла:
file_put_contents('nette.safe://file', $s);
$s = file_get_contents('nette.safe://file');
SafeStream гарантира, че не повече от една нишка може да записва във файла едновременно. Другите нишки чакат в опашката. Ако никоя нишка не пише, произволен брой нишки могат да четат файла паралелно.
Всички нормални функции на PHP могат да се използват с протокола, напр:
// 'r' означава отворен само за четене
$handle = fopen('nette.safe://file.txt', 'r');
$ini = parse_ini_file('nette.safe://translations.neon');