(PHP 4, PHP 5)
flock — 汎用のファイルロックを行う
$handle
, int $operation
[, int &$wouldblock
] )flock() を使うと、(ほとんどの Unix、そして Windows さえ含む) 事実上すべてのプラットフォームで使用可能な、簡易な読み手/書き手モデルを実現できます。
PHP 5.3.2 より前のバージョンでは、 fclose() でロックの解放も行います (これは、スクリプトが終了した場合にも自動的にコールされます)。
PHP は、恣意的にファイルをロックする汎用の手段を提供します
(これは、アクセスする全プログラムが同一のロックの方法を使用する必要があり、
そうでない場合は動作しないことを意味します)。
デフォルトでは、要求したロックが確保されるまでこの関数はブロックします。
(非 Windows プラットフォームでは) 以下で説明する LOCK_NB
オプションでこの挙動を制御することができます。
handle
fopen() を使用して作成したファイルシステムポインタリソース。
operation
operation
は以下のいずれかとなります。
LOCK_SH
をセットします。
LOCK_EX
をセットします。
LOCK_UN
をセットします。
上の操作のいずれかに LOCK_NB
をビットマスクとして追加すれば、
ロック中に flock() でブロックを行わないことができます
(Windows ではサポートされていません)。
wouldblock
ロックがブロックされた (errno が EWOULDBLOCK となった)
場合に、オプションの 3 番目の引数に TRUE
が設定されます。
成功した場合に TRUE
を、失敗した場合に FALSE
を返します。
バージョン | 説明 |
---|---|
5.3.2 | ファイルのリソースハンドルを閉じたときにロックを自動的に解放する機能が削除されました。 ロックの解放は、常に手動で行わなければなりません。 |
4.0.1 |
定数 LOCK_XXX が追加されました。以前のバージョンでは
LOCK_SH のかわりに 1、
LOCK_EX のかわりに 2、
LOCK_UN のかわりに 3、そして
LOCK_NB のかわりに 4 を使用しなければなりません。
|
例1 flock() の例
<?php
$fp = fopen("/tmp/lock.txt", "r+");
if (flock($fp, LOCK_EX)) { // 排他ロックを確保します
ftruncate($fp, 0); // ファイルを切り詰めます
fwrite($fp, "ここで何かを書きます\n");
fflush($fp); // 出力をフラッシュしてからロックを解放します
flock($fp, LOCK_UN); // ロックを解放します
} else {
echo "ファイルを取得できません!";
}
fclose($fp);
?>
例2 flock() で LOCK_NB
オプションを使う例
<?php
$fp = fopen('/tmp/lock.txt', 'r+');
/* LOCK_NB オプションを LOCK_EX で有効にします */
if(!flock($fp, LOCK_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() メソッドを実装した ユーザー空間のストリームを指すファイルポインタに対してのみ使うことができます。
一連のコードで別の値を handle
引数に代入すると、
それ以降のコードでロックを解放します。
いくつかのオーペレーティングシステムで flock() はプロセスレベルで実装されています。ISAPIのようなマルチスレッド 型のサーバーAPIを使用している場合、同じサーバーインスタンスの並 列スレッドで実行されている他のPHPスクリプトに対してファイルを保 護する際に flock()を使用することはできません!
flock()はFATのような
旧式のファイルシステムではサポートされていないため、
そのような環境の場合は常にFALSE
を返すことになります。
(これは特にWindows98ユーザーにとって常に真です)