MW211 EXIT

devlog
PHP/file関数の排他制御
2013年02月21日
「file()」や「file_get_contents()」では排他制御ができない。

排他制御には「flock()」が必要で、この引数の一つがファイルポインタで、
つまりは、ファイルポインタがないと排他制御ができないのだが、
「file()」や「file_get_contents()」はファイルポインタがない
(敢えて意識しないような作りの)関数だからだ。

ま、読み込む分には、リトライとか必要ないからそれでいいのかもしれないが、
書き込みとセットで「読み込み~書き込み」の間を独占したい場合には、
排他制御が必要となってくる。

ということで、実現方法としては、ダミーの排他用ファイルを用意して、
そちらで排他の真似事のようなこと(といっても思いっきり排他だけど)をする。

  (1) 排他用ファイルをロックする
  (2) 「file()」とかを使って読み込む
  (3) 「fopen()」「fwrite()」「fclose()」を組み合わせて書き込む
  (4) 排他用ファイルをアンロックする

これにより、(1)~(4)の区間が排他占有となり、(2)と(3)も排他占有となるという寸法。
┌──────────────────────────────────────┐
│$fp = fopen('lock.txt','w');                                                │
│flock($fp, LOCK_EX);                                                        │
├──────────────────────────────────────┤
│fclose($fp);                                                                │
└──────────────────────────────────────┘
「flock()」の対義語的な「funlock()」(そんなのないけど)は、
「fclose()」が内包してくれてる感じかな。

追記:と思ったら、PHP5.3.2以降ではアンロックを
      「fclose()」が内包してくれない仕様になってしまった
…というわけで続く。。。
分類:PHP