2017-09-02 4 views
0

私は同時に同じファイルに複数のユーザーが同時に書き込むことができるWebサイトを持っています。私のコードの例は以下の通りです。複数のユーザーがPHPを使用して同じファイルに同時に書き込みます

PHP 5.6.20

<?php 
$root=realpath($_SERVER["DOCUMENT_ROOT"]); 
$var=time()."|"; 
echo $var."<br/>"; 
$filename=$root."/Testing/Testing/test1.txt"; 

$myfile=fopen($filename,"a"); 
fwrite($myfile,$var); 
fclose($myfile); 

$myfile=fopen($filename,"r"); 
$contents = fread($myfile, filesize($filename)); 
echo $contents; 
fclose($myfile); 
?> 

私はのI、複数のユーザーが同じファイルを同じファイルに書き込みをしようとしている場合はPHPで、データ破損の可能性があることを読んでコースでは、長期的にはデータの破損を引き起こす可能性のあるコードを持つことは望ましくありません。

私はブラウザ上でほぼ同時に同じコードを実行しようとしましたが、同時に複数のユーザーが同じファイルに書き込むのをシミュレートしました。エラーが発生したり、書き込み中のファイルにデータが破損したりしませんでした。しかし、私はまだ将来のデータ破損についてはわかりません。

私はflockを使って2人のユーザーが同時にファイルに書き込めないことを確認しましたが、上記のコードをテストしてデータ破損が発生していないため、私のコードをflockで更新するか、まるでそのままにしておいてください。

私の質問は以下のとおりです。

1)は、それはへの書き込みのファイルを破損、上記のコードのいずれかの可能性はありますか?

2)そうなら、flockを使用してこの問題を解決しますか?はいの場合、私は上記のコードで群を実装する必要がありますか?

編集:

私はこの不確実性は、データベースを使用することによって解決することができることを知っているが、このような場合のために、それはDBを使用するので、私を提案しないでください、プレーンテキストを使用することをお勧めします。

ありがとうございます。

+0

このコードは、ファイルを破損させる可能性があります。あなたはファイルに追加しているので、大丈夫かもしれません。これをログファイルとして使用している場合は、問題ありません。 flockを使用すると、コードが待機し、そのコードを使用しているユーザーに遅延が発生します。 – ryantxr

+0

ファイルに追加しているため、大丈夫かもしれません。それは大丈夫じゃないの? "w"でファイルに書き込むときです。私はそれを試したので、データの破損もありませんでした。 –

+0

ユーザーが代わりにデータベースに書き込めない理由はありますか?ファイルは読み込みに適しています(インクルードなどを介して)が、あなたが正しいです、あなたは権利中に競合する可能性があります。それはデータベースでも解決されないかもしれません。たとえば、古いMyISAMテーブルタイプでMySQLを使用する場合です。しかし、InnoDBに固執すれば、あなたはすべて設定されます。だから、あなたが最初にファイルを選択する理由が不思議です。あなたの質問を解決しないで申し訳ありません。 –

答えて

0

これは、多くのプログラミング言語の多くのWebアプリケーションで一般的な理論上の問題です。

答えははいです。問題が発生する可能性があります。しかし、これは非常に理論的な問題です。ファイルに追加するコンテンツがそれほど大きくなく、トラフィックが多い場合は問題になります。今日のオペレーティングシステムとファイルシステムは、ファイルハンドルを使用した直後にファイルハンドルを閉じると、非常にうまく最適化されます(キャッシング、遅延書き込みなど)。

エラーが発生した場合(他の言語でPHP /例外をキャッチする前にアクセス権を確認してください)、遅延の後に再試行したり、バッファを一時ファイルに書き込んだりしてマージすると、バッファのようなものを追加できます別のプロセスでは、いくつかの可能性があります。

そして、flock()はこれらの目的には良い機能かもしれませんが、それはすでに過剰に設計されていると思います。

+0

によれば、「ファイルハンドルを使用した直後にファイルハンドルを閉じると、非常に起こりそうもない」と述べています。私は、私のサーバー上で同時にPHPスクリプトを2回実行した瞬間までに、まったく同じことを思っていたことを伝えることができます。これはひどく構成されたタスクでしたが、それは起こります。 –

+0

良い例。しかし、cronjobの場合、ロックを書くのは簡単だろう;-) – iquellis

+0

@iquellis Flockを使用すると、ファイルに破損したデータが得られないことが本当に保証できますか?はいの場合は、コードにflockを追加して回答を編集できますか? –

0

単純なファイルからトランザクションを使用して任意のデータベースに保存メカニズムを変更する必要があります。

+0

私はデータベースを使いたくないので、プレーンテキストを使いたいです。 –

+1

私はあなたが望むものを理解していますが、PHPスクリプトからファイルを完全に制御することはできません。上記のトリックはすべて99%で動作しますが、この1%を制御することはできません。このため、データベースでは取引の仕組みがあります。 –

0

2つのスクリプトが同時にファイルに書き込もうとした場合。 fopen()関数は、ファイルに対して呼び出されたときに、同じファイルが別のスクリプトによって開かれるのを止めるわけではありません。つまり、ファイルから別のスクリプトが読み込まれるか、同じファイルを同時にだから、flock()を使うのは良いことです。 http://www.hackingwithphp.com/8/11/0/locking-files-with-flockについての詳しいヘルプが表示されます。あなたのコードのためにあなたが

<?php 
$root=realpath($_SERVER["DOCUMENT_ROOT"]); 
$var=time()."|"; 
echo $var."<br/>"; 
$filename=$root."/Testing/Testing/test1.txt"; 

$myfile=fopen($filename,"a"); 
if (flock($myfile, LOCK_EX)) {   
    fwrite($myfile,$var); 
    flock($fp, LOCK_UN); // unlock the file 
} else { 
    // flock() returned false, no lock obtained 
    print "Could not lock $filename!\n"; 
} 

fclose($myfile); 

$myfile=fopen($filename,"r"); 
if (flock($myfile, LOCK_EX)) {   

    $contents = fread($myfile, filesize($filename)); 
    echo $contents; 
    flock($fp, LOCK_UN); // unlock the file 
} else { 
    // flock() returned false, no lock obtained 
    print "Could not lock $filename!\n"; 
} 
fclose($myfile); 
?> 
+0

ファイルを読み取るときにLOCK_EXを使用したのはなぜですか?LOCK_SHを使用して、複数のユーザーがファイルを同時に読み取ることができないようにしてください。どう思いますか、 ? –

+0

ええ、ファイルを読み込んでいるときにLOCK_SHを使うことができます。しかし、書いている間は、LOCK_EXを使う必要があります。これは、一度に1つのプロセスだけが書き込むことができるからです。 –

0

として群れを()を使用することができ 私は群れに慣れていないんだけど、私の最初に考えたのは、ロックまたはキューイングメカニズムです。書き込まれたデータを使用する必要がないか、またはユーザーに表示する必要がない場合は、作業キューが最適な選択肢になります。データをredisまたはmemcachedベースのシステム、SQLまたは他のタイプの待ち行列システムに書き込むか、ワーカーが昇順で集計ファイルに集めることができるディレクトリに興味のあるコンテンツを持つユニークなタイムスタンプ付きファイルをダンプするだけです。

書かれたデータがレポートや結果を返すために必要なものをトリガする場合や、フィードバックやその他のフィードバックが必要な場合は、非同期スタックに再設計できない場合最終的な一貫性を持つ。同時ユーザーの数と負荷、サーバーの数などを把握することも難しいです。

関連する問題