SafeStream: Dosyalara Güvenli Erişim
Nette SafeStream, bir dosyaya her okuma ve yazma işleminin izole olarak gerçekleşmesini garanti eder. Bu, hiçbir iş parçacığının henüz tamamen yazılmamış bir dosyayı okumaya başlamayacağı veya birden fazla iş parçacığının aynı dosyanın üzerine yazmayacağı anlamına gelir.
Kurulum:
composer require nette/safe-stream
Ne işe yarar?
İzole operasyonlar aslında ne işe yarar? Bir dosyaya tekrar tekrar yazan ve ardından aynı dizeyi ondan okuyan basit bir örnekle başlayalım:
$s = str_repeat('Uzun Dize', 10000);
$counter = 1000;
while ($counter--) {
file_put_contents('dosya', $s); // yaz
$readed = file_get_contents('dosya'); // oku
if ($s !== $readed) { // kontrol et
echo 'dizeler farklı!';
}
}
echo 'dizeler farklı!'
çağrısının asla gerçekleşemeyeceği görünebilir. Tam tersi doğrudur. Bu betiği
aynı anda iki tarayıcı sekmesinde çalıştırmayı deneyin. Hata pratikte hemen ortaya çıkar.
Sekmelerden biri dosyayı, diğeri henüz tamamen yazmayı bitirmediği bir anda okur, bu nedenle içerik tam olmaz.
Bu nedenle, belirtilen kod aynı anda birden çok kez yürütülürse (yani birden çok iş parçacığında) güvenli değildir. Bu internette alışılmadık bir durum değildir, genellikle sunucu aynı anda çok sayıda kullanıcıya yanıt verir. Bu nedenle, uygulamanızın birden çok iş parçacığında yürütüldüğünde bile güvenilir bir şekilde çalışmasını sağlamak (iş parçacığı güvenli) çok önemlidir. Aksi takdirde, veri kaybı ve tespit edilmesi zor hatalar oluşur.
Ancak gördüğünüz gibi, dosyaları okumak ve yazmak için yerel PHP fonksiyonları izole ve atomik değildir.
SafeStream Nasıl Kullanılır?
SafeStream, standart PHP fonksiyonları aracılığıyla dosyaları izole olarak okuyup yazabileceğiniz güvenli bir protokol
oluşturur. Dosya adının önüne nette.safe://
eklemeniz yeterlidir:
file_put_contents('nette.safe://dosya', $s);
$s = file_get_contents('nette.safe://dosya');
SafeStream, aynı anda en fazla bir iş parçacığının bir dosyaya yazabilmesini sağlar. Diğer iş parçacıkları kuyrukta bekler. Hiçbir iş parçacığı yazmıyorsa, herhangi bir sayıda iş parçacığı dosyayı paralel olarak okuyabilir.
Protokolle birlikte tüm yaygın PHP fonksiyonları kullanılabilir, örneğin:
// 'r', yalnızca okuma için aç anlamına gelir
$handle = fopen('nette.safe://file.txt', 'r');
$ini = parse_ini_file('nette.safe://translations.neon');