(PHP 4, PHP 5)
flock — 汎用のファイルロックを行う
flock() を使うと、(ほとんどの Unix、そして Windows さえ含む) 事実上すべてのプラットフォームで使用可能な、簡易な読み手/書き手モデルを実現できます。
PHP 5.3.2 より前のバージョンでは、fclose() でロックの解放も行います (これは、スクリプトが終了した場合にも自動的にコールされます)。
PHP は、恣意的にファイルをロックする汎用の手段を提供します (これは、アクセスする全プログラムが同一のロックの方法を使用する必要があり、 そうでない場合は動作しないことを意味します)。 デフォルトでは、要求したロックが確保されるまでこの関数はブロックします。 (非 Windows プラットフォームでは) 以下で説明する LOCK_NB オプションでこの挙動を制御することができます。
fopen() を使用して作成したファイルシステムポインタリソース。
operation は以下のいずれかとなります。
上の操作のいずれかに LOCK_NB をビットマスクとして追加すれば、 ロック中に flock() でブロックを行わないことができます (Windows ではサポートされていません)。
ロックがブロックされた (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, "Write something here\n");
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ユーザーにとって常に真です)