SafeStream: ファイルへの安全なアクセス

Nette SafeStreamは、ファイルへのすべての読み取りと書き込みが分離して行われることを保証します。これは、まだ完全に書き込まれていないファイルを読み取り始めるスレッドがないこと、または複数のスレッドが同じファイルを上書きしないことを意味します。

インストール:

composer require nette/safe-stream

何が良いのですか?

分離された操作は何が良いのでしょうか? ファイルに繰り返し書き込み、その後同じ文字列を読み取る簡単な例から始めましょう:

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

$counter = 1000;
while ($counter--) {
	file_put_contents('soubor', $s); // 書き込みます
	$readed = file_get_contents('soubor'); // 読み取ります
	if ($s !== $readed) { // チェックします
		echo '文字列が異なります!';
	}
}

echo '文字列が異なります!'の呼び出しが決して起こらないように思えるかもしれません。しかし、逆が真実です。このスクリプトをブラウザの2つのタブで同時に実行してみてください。エラーはほぼ即座に発生します。

タブの1つが、もう1つがまだ完全に書き込み終えていない瞬間にファイルを読み取るため、内容が完全ではありません。

したがって、上記のコードは、同時に複数回(つまり複数のスレッドで)実行される場合、安全ではありません。これはインターネットでは珍しいことではなく、サーバーはしばしば同時に多数のユーザーに応答します。したがって、アプリケーションが複数のスレッドで実行されても(スレッドセーフ)、確実に機能するようにすることは非常に重要です。そうしないと、データが失われ、検出が困難なエラーが発生します。

しかし、ご覧のとおり、ファイルの読み取りと書き込みのためのネイティブPHP関数は分離されておらず、アトミックではありません。

SafeStream の使用方法は?

SafeStreamは、標準のPHP関数を使用してファイルを分離して読み書きできる安全なプロトコルを作成します。ファイル名の前にnette.safe://を付けるだけです:

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

SafeStreamは、一度に最大1つのスレッドのみがファイルに書き込むことができることを保証します。他のスレッドはキューで待機します。書き込み中のスレッドがない場合、任意の数のスレッドがファイルを並行して読み取ることができます。

このプロトコルでは、すべての一般的なPHP関数を使用できます。例:

// 'r' は読み取り専用で開くことを意味します
$handle = fopen('nette.safe://file.txt', 'r');

$ini = parse_ini_file('nette.safe://translations.neon');
バージョン: 3.0