2009-07-30 80 views
19

私は同じファイルに書き込む2つの異なるPHPファイルを持っています。各PHPスクリプトは、2つの異なるHTMLページのユーザーアクションによって呼び出されます。 2つのPHPファイルを呼び出すことは可能ですが、両方のPHPファイルが同時にファイルに書き込もうとしますか?はいの場合はどうなりますか?また、あるPHP関数が他のPHP関数よりも重要ではないので、PHPのいずれかが正常に機能しなくなる(ファイル書き込みは失敗し、他のPHPはファイルに書き込むことができます)。PHP同時ファイル書き込み

答えて

28

これに対処する通常の方法は、ロックするために、両方のスクリプトがflock()を使用することです:

$f = fopen('some_file', 'a'); 
flock($f, LOCK_EX); 
fwrite($f, "some_line\n"); 
flock($f, LOCK_UN); 
fclose($f); 

これは、スクリプトがそれに書き込む前にファイルを成し遂げるためにお互いを待つことになります。あなたが好きなら、「あまり重要」スクリプトが実行できます。

$f = fopen('some_file', 'a'); 
if(flock($f, LOCK_EX | LOCK_NB)) { 
    fwrite($f, "some_line\n"); 
    flock($f, LOCK_UN); 
} 
fclose($f); 

それが何かは、ファイルとビジーであることを発見した場合、それだけで何もしませんように。

+0

私が探していたもの!それは簡単だったので、PHPのドキュメントをもっと調べてみるべきでした。 –

+0

関数がアトミックではないので、flock()を使用して注意してください。 – arul

+0

2つの正確な同時書き込みでファイルの内容が空にならないようにするもう1つのヒント。フラットファイルのビジターカウンターを持つ人気の高いページで、それは私にはたくさん起こった。解決策:fwrite()の前に20〜80 msのランダムな遅延を追加しました。これは、現在までにビジター数がはるかに多いという問題を修正しました。 –

-4

FYI:群がるだけの* nix上で動作しますのでご注意くださいWindowsの

+2

PHPのドキュメントから: "flock()は、ほぼすべてのプラットフォーム(ほとんどのUnix派生物やWindowsを含む)で使用できる単純なリーダー/ライターモデルを実行することを可能にします。 – cdmckay

+1

システムコールとしての 'flock'はWindowsでは実装されていませんが、これは' flock' PHP関数で抽象化されています。 – Piskvor

+1

ええ、私は誤って話しました。これは私がWindowsで利用できないと言ったときに考えていたバグです:http://bugs.php.net/bug.php?id = 39138(私はWindowsのローカルデベロッパーサーバーに必要な時にこれに遭遇し、それ以来Windowsマシンでそれを避けていた)。冷静に、戦い続けよ。 – xentek

9

利用できません:ファイルのリソースハンドルが削除された閉じられたときにPHP 5.3.2、自動ロック解除のよう

。 ロック解除は常に手動で行う必要があります。

更新下位互換性のコードは次のとおりです。

if (($fp = fopen('locked_file', 'ab')) !== FALSE) { 
    if (flock($fp, LOCK_EX) === TRUE) { 
     fwrite($fp, "Write something here\n"); 
     flock($fp, LOCK_UN); 
    } 

    fclose($fp); 
} 

つまりあなたはfcloseを()はもうそれをしないため、明示的に群れ(..、LOCK_UN)を呼び出す必要があります。

11

ファイルが開かれている場合、posixはアブストラクトになります。にはが追加されます。つまり、ファイルに複数のスレッドを追加するだけで、行が破損することはありません。

私は十数本のスレッドと数十万本でこれをテストしました。いずれの線も壊れていない。

バッファサイズが超過する可能性があるため、これは1kBを超える文字列では機能しない可能性があります。

これは、posixに準拠していないウィンドウでは機能しない可能性があります。

関連する問題