PHP でのファイル操作では、複数のユーザーが同時に操作する場合の競合を避けるために、主にファイル ロックを使用します。以下では、エディターがファイル ロックの排他操作のいくつかの例をテストおよび分析します。
flock – 軽量の勧告ファイルロック
flock() 関数のプロトタイプ
bool flock ( int ハンドル, int 操作 [, int &wouldblock] )
PHP は、勧告的な方法ですべてのファイルをロックする軽量の方法をサポートしています (つまり、アクセスするすべてのプログラムは同じ方法でロックする必要があります。そうしないと機能しません)
操作は次のいずれかの値になります:
共有ロック (プログラムの読み取り) を取得するには、操作を LOCK_SH に設定します (PHP 4.0.1 より前のバージョンでは 1 に設定)。
排他ロックを取得するには(プログラムの書き込み)、操作を LOCK_EX に設定します(PHP 4.0.1 より前のバージョンでは 2 に設定)。
ロック (共有または排他) を解放するには、操作を LOCK_UN に設定します (PHP 4.0.1 より前のバージョンでは 3 に設定)。
flock() がロック時にブロックしないようにするには、操作に LOCK_NB を追加します (PHP 4.0.1 より前のバージョンでは 4 に設定)。
flock() を使用すると、任意のプラットフォーム (ほとんどの Unix 派生製品や Windows も含む) で使用できる単純な読み取り/書き込みモデルを実装できます。ロックがブロックされる場合 (EWOULDBLOCK エラー コードの場合)、オプションの 3 番目のパラメーターは TRUE に設定されます。ロック操作は fclose() によって解放することもできます (コードの実行が完了すると自動的に呼び出されます)。
成功した場合は TRUE を返し、失敗した場合は FALSE を返します。
注:
Windows では flock() が強制されます。 flock() 操作のハンドルは、開いているファイル ポインターである必要があります。
flock() にはファイル ポインターが必要なため、書き込みモードで開くことを目的としたファイルへのアクセスを保護するために、特別なロック ファイルを使用する必要がある場合があります (fopen() 関数に「w」または「w+」を追加します)。
flock() は、NFS およびその他の一部のネットワーク ファイル システムでは使用できません。 flock() は、FAT やその派生物などの古いファイル システムをサポートしません。したがって、この環境では常に FALSE を返します (特に Windows の場合)。詳細については、オペレーティング システムのドキュメントを確認してください。
一部のオペレーティング システムでは、flock() がプロセス レベルで実装されます。マルチスレッド サーバー API (ISAPI など) を使用する場合、ファイルを保護するために flock() に依存することができない場合があります。これは、ファイルが同じサーバー インスタンス内の他の並列スレッドで実行されている PHP スクリプトによって処理される可能性があるためです。
独占テスト:
次の 2 つのファイルは似ていますが、書かれている内容が異なることが最初に a.php ファイルを実行して開いたままにし、次に b.php ファイルを実行して、書き込まれたファイルの内容を確認するとわかります。 b. php ファイルの内容が正常に書き込まれませんでした。
コードは次のとおりです | コードをコピー |
// a.php
// b.php |
たとえば、次のような 2 つのファイルがあります。
flocka.php
コードは次のとおりです | コードをコピー |
$file = 'temp.txt'; $fp = fopen($file,'a'); for($i = 0;$i { fwrite($fp, "11111111n"); 睡眠(1); } fclose($fp); |
コードは次のとおりです | コードをコピー |
$file = 'temp.txt'; $fp = fopen($file,'a'); for($i = 0;$i { fwrite($fp, "22222222n"); } fclose($fp); |
結果:
11111111
22222222
22222222
22222222
22222222
22222222
11111111
11111111
11111111
11111111
ファイル ロックが追加されていない場合、2 つのファイルが同時に txt ファイルに書き込まれることに注意してください。
2 つの php ファイルのコードを変更してみましょう。
flocka.php
コードをコピー | |
$fp = fopen($file,'a'); If(flock($fp,LOCK_EX)) { for($i = 0;$i { fwrite($fp, "11111111n"); 睡眠(1); } 群れ($fp,LOCK_UN); } fclose($fp); |
コードをコピー | |
If(flock($fp,LOCK_EX)) { for($i = 0;$i { fwrite($fp, "22222222n"); } 群れ($fp,LOCK_UN); } fclose($fp); | 同様に、最初に flocka.php を実行し、その後すぐに flockb.php を実行します。
11111111
11111111
11111111
11111111
11111111
22222222
22222222
22222222
22222222
22222222
また、flockを実行するとファイルのロックが自動的に解除されます