ファイルロック
基本
$filePath = 'path/to/file.txt'; $fp = fopen($filePath, 'rb+'); flock($fp, LOCK_EX); // $fpを使ってごにょごにょ flock($fp, LOCK_UN); fclose($fp);
注意
ファイルポインタを使わないアクセス
Windows上で動かす場合。Linux上では問題ない。Macは知らん。
PHPにはfile_get_contents()
など、ファイルポインタを使わずとも中身を取得できる便利な関数がいくつかあるが、これらの関数はロック中のファイルへはアクセスできない。また、hash_file()
も、ロック中は中身を読み取れないため常に(どんなファイルであっても)同じ値を返す。
$filePath = 'path/to/file.txt'; $fp = fopen($filePath, 'rb+'); flock($fp, LOCK_EX); var_dump(file_get_contents($path)); // -> string(0) "" // 中身は表示されない。 var_dump(hash_file('sha256', $path)); // -> string(64) "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" // これは""(空文字列)をハッシュ化した値と等しい var_dump(filesize($path)); var_dump(filemtime($path)); // ファイルサイズやファイル更新時刻。こーゆーのは大丈夫。 flock($fp, LOCK_UN); fclose($fp);
ロックしつつfile関数を使いたい
根本的な解決ではないが、ロック専用ファイルを作り、そちらを代わりにロックする。「目的のファイルへは、必ずこのファイルをロックしてからアクセスする」という約束を守る。
$filePath = 'path/to/file.txt'; $lockPath = 'path/to/file.lock'; $lock_fp = fopen($lockPath, 'w'); // 'w'にしておくとファイルがなくても作られる flock($lock_fp, LOCK_EX); $content = file_get_contents($filePath); flock($lock_fp, LOCK_UN); fclose($lock_fp);