SafeStream: Sicherheit für Dateien

Nette SafeStream garantiert, dass jeder Lese- und Schreibvorgang in einer Datei isoliert ist. Das bedeutet, dass kein Thread mit dem Lesen einer Datei beginnt, die noch nicht vollständig geschrieben ist, oder dass mehrere Threads dieselbe Datei nicht überschreiben.

Installation:

composer require nette/safe-stream

Wozu ist sie gut?

Wozu sind isolierte Operationen eigentlich gut? Beginnen wir mit einem einfachen Beispiel, bei dem wiederholt in eine Datei geschrieben und dann dieselbe Zeichenkette aus ihr gelesen wird:

$s = str_repeat('Long String', 10000);

$counter = 1000;
while ($counter--) {
	file_put_contents('file', $s); // schreiben
	$readed = file_get_contents('file'); // lesen
	if ($s !== $readed) { // prüfen
		echo 'Zeichenketten sind unterschiedlich!';
	}
}

Es mag den Anschein haben, dass echo 'strings differ!' niemals auftreten kann. Das Gegenteil ist der Fall. Versuchen Sie, dieses Skript in zwei Browser-Registerkarten gleichzeitig auszuführen. Der Fehler wird fast sofort auftreten.

Eine der Registerkarten liest die Datei zu einem Zeitpunkt, zu dem die andere noch keine Gelegenheit hatte, sie vollständig zu schreiben, so dass der Inhalt nicht vollständig ist.

Daher ist der Code nicht sicher, wenn er mehrmals gleichzeitig ausgeführt wird (d. h. in mehreren Threads). Das ist im Internet nicht unüblich, da ein Server oft auf eine große Anzahl von Benutzern gleichzeitig reagiert. Daher ist es sehr wichtig, dass Ihre Anwendung auch dann zuverlässig funktioniert, wenn sie in mehreren Threads ausgeführt wird (thread-safe). Andernfalls gehen Daten verloren und es treten schwer zu erkennende Fehler auf.

Aber wie Sie sehen, sind die PHP-eigenen Funktionen zum Lesen und Schreiben von Dateien nicht isoliert und atomar.

Wie benutzt man SafeStream?

SafeStream erstellt ein sicheres Protokoll zum Lesen und Schreiben von Dateien in Isolation unter Verwendung von PHP-Standardfunktionen. Alles, was Sie tun müssen, ist, nette.safe:// vor dem Dateinamen anzugeben:

file_put_contents('nette.safe://file', $s);
$s = file_get_contents('nette.safe://file');

SafeStream sorgt dafür, dass immer nur ein Thread in die Datei schreiben kann. Die anderen Threads warten in der Warteschlange. Wenn kein Thread schreibt, kann eine beliebige Anzahl von Threads die Datei parallel lesen.

Alle gängigen PHP-Funktionen können mit dem Protokoll verwendet werden, zum Beispiel:

// 'r' bedeutet schreibgeschützt öffnen
$handle = fopen('nette.safe://file.txt', 'r');

$ini = parse_ini_file('nette.safe://translations.neon');
Version: 3.0