昨年から PHP7で動作するよう rNote を修正して使用していたが、PHPマニュアルサイトの flock() の説明によると、 PHP 5.3.2 以降は、 flock($fp, LOCK_EX); などでロックしたファイルは、 fclose($fp); の直前で明示的に flock($fp, LOCK_UN); を呼んでアンロックしてやらないといけないことに気づいたので grep で検索してみたら、結構あちこちでアンロックを明示的に呼んでいなかった。

そこで、 flock($fp, LOCK_UN); を明示的に呼びだすように修正した。(修正しなくても特に問題なく動作していたが、 PHP の仕様上正しくロックしなくなっていたはず。)

特に気を付けたいのが rnote.php で下のように定義されている _fopen_wb() 。


function _fopen_wb($fname){
    $fp = @fopen($fname, "wb");
    if(! $fp) error("$fname : File write error");
    set_file_buffer($fp, 0);
    flock($fp, LOCK_EX);
    rewind($fp);
    return $fp;
}

この関数の中では $fp = fopen() が呼ばれ、開かれたファイルをロックしているのだが、アンロックしないまま fclose($fp); も呼ばず、そのまま $fp を返り値として返しているので、_fopen_wb() を呼び出した側で、受け取った $fp を使用した後に fclose($fp) する直前で明示的に flock($fp, LOCK_UN); を呼ばなければいけない。コードとしてはかなり見通しが悪くなり汚いコードになるが仕方がないのでそのように修正した。

[コメントの受付は終了しています ]
この記事のリンク元

キーワード: rNote php flock