PHP入門 ファイルシステム関数 ファイルのロック(flock関数)

ファイルへの同時書き込みを制御するflock関数について解説。

構文:flock関数

flock(resource $stream, int $operation):bool
$streamファイルハンドル
$operationロックモード

あるユーザーがファイルを開いて書き込んでいる間に、別のユーザーが元のファイルを開いて、別の書き込みを行った場合、処理内容によってはファイルが破壊されてしまいます。共有のリソースに対して書き込みを行う場合は、PHPでは、flock関数を利用することで、直感的にファイルをロック/アンロックできます。

flock($file, LOCK_EX);

利用可能なロックモード

設定値概要
LOCK_SH共有ロック(読み込み中なので、他者による書き込みを禁止する)
LOCK_EX排他ロック(書き込み中なので、他者による読み書きを禁止する)
LOCK_UNロックの解除
LOCK_NB非ブロックモード

共有ロックとは「自分がファイルを読み込んでいる場合は、他の人は書き込めない。(読み込みはOK)」と制限するロック、排他ロックとは「自分が今ファイルを書き込んでいるいので、他の人は読み込みも書き込みもできない。」と制限するロックです。それぞれ読み込み/書き込み時に指定するロックであることから、読み込みロック、書き込みロックと呼ばれる場合もあります。排他ロック(LOCK_EX)を指定しているので、複数のユーザーが同時にアクセスした場合、片方のユーザーはもう片方のユーザーの処理が終わるまで処理待ちとなります。ロック解除するには、flock関数でLOCK_UNを指定します。以前はfclose関数によるファイルクローズのタイミングで自動的にアンロックされていましたが、PHP5.3.2以降でその機能は削除されています。

ロックモードの中でLOCK_NBだけはやや特殊な値で、単独では指定できません。「LOCK_SH|LOCK_NB」「LOCK_EX|LOCK_NB」のように、論理和(|)演算子で他の設定値と結合したものを指定します。
「| LOCK_NB」を付けた場合と付けない場合とでは、対象となるファイルがロックされているときの挙動が異なります。LOCK_SHとLOCK_EXは、既定では対象ファイルがロックされているときに自分がロックできるようになるまで待機しますが(ブロックモード)、「LOCK_NB」付きのLOCK_SHとLOCK_EXは即座に結果(false)を返します(非ブロックモード)