flock

汎用のファイルロックを行う

説明

bool flock(resource $stream, int $operation, int &$would_block = null)

flock を使うと、(ほとんどの Unix、そして Windows さえ含む) 事実上すべてのプラットフォームで使用可能な、簡易な読み手/書き手モデルを実現できます。

ロックの解放は、fclose が実行されるか、 stream がガベージコレクションされた段階で行われます。

PHP は、恣意的にファイルをロックする汎用の手段を提供します (これは、アクセスする全プログラムが同一のロックの方法を使用する必要があり、 そうでない場合は動作しないことを意味します)。 デフォルトでは、要求したロックが確保されるまでこの関数はブロックします。 以下で説明する LOCK_NB オプションでこの挙動を制御することができます。

パラメータ

stream

fopen を使用して作成したファイルシステムポインタリソース。

operation

operation は以下のいずれかとなります。

  • 共有ロック(読み手)とするには LOCK_SH をセットします。
  • 排他的ロック(書き手)とするには LOCK_EX をセットします。
  • (共有または排他的)ロックを開放するには LOCK_UN をセットします。

ロックを試みている間に flock がブロックすべきでない場合は、上の操作のいずれかに LOCK_NB をビットマスクとして追加できます。

would_block

ロックがブロックされた (errno が EWOULDBLOCK となった) 場合に、オプションの 3 番目の引数に 1 が設定されます。

戻り値

成功した場合に true を、失敗した場合に false を返します。

例1 flock の例

<?php

$fp 
fopen("/tmp/lock.txt""r+");

if (
flock($fpLOCK_EX)) {  // 排他ロックを確保します
    
ftruncate($fp0);      // ファイルを切り詰めます
    
fwrite($fp"ここで何かを書きます\n");
    
fflush($fp);            // 出力をフラッシュしてからロックを解放します
    
flock($fpLOCK_UN);    // ロックを解放します
} else {
    echo 
"ファイルを取得できません!";
}

fclose($fp);

?>

例2 flockLOCK_NB オプションを使う例

<?php
$fp 
fopen('/tmp/lock.txt''r+');

/* LOCK_NB オプションを LOCK_EX で有効にします */
if(!flock($fpLOCK_EX LOCK_NB)) {
    echo 
'Unable to obtain lock';
    exit(-
1);
}

/* ... */

fclose($fp);
?>

注意

注意:

flock は、Windows 上ではアドバイザリロックではなく 強制ロックを使います。強制ロックは Linux や System V 系の OS でもサポートされています。 これは、そのファイルに setgid パーミッションが設定されていて グループの実行ビットがクリアされている場合に fcntl() システムコールが通常サポートしている方式です。 Linux では、これを行うには mand オプションつきでファイルシステムをマウントしておく必要があります。

注意:

flockは、ファイルポインタを必要とするため、 (fopenへ引数"w"または"w+"を指定して)書き込 みモードでオープンすることにより丸めるファイルにアクセス保護する 特別なロックファイルを使用する必要があるかもしれません。

注意:

fopen が返すローカルファイルへのポインタ、あるいは streamWrapper::stream_lock メソッドを実装した ユーザー空間のストリームを指すファイルポインタに対してのみ使うことができます。

警告

一連のコードで別の値を stream 引数に代入すると、 それ以降のコードでロックを解放します。

警告

いくつかのオーペレーティングシステムでflock はプロセスレベルで実装されています。マルチスレッド 型のサーバーAPIを使用している場合、同じサーバーインスタンスの並 列スレッドで実行されている他のPHPスクリプトに対してファイルを保 護する際に flockを使用することはできません!

flockFATのような 旧式のファイルシステムではサポートされていないため、 これらの環境の場合は常にfalseを返すことになります。

注意:

Windows では、 ロックするプロセスが同じファイルを二回オープンする場合、 ファイルをアンロックするまで二番目のハンドルではアクセスできません。