2013-03-15 9 views
6

入力をテキストファイルに書き込むフォームがあります。 テキストファイルを編集用にロックし、「ファイルが別のユーザーによって編集されました。後でやり直してください」というフレンドリーなメッセージを表示することは可能でしょうか?PHPは編集用のテキストファイルをロックしていますか?

ファイルに複数のエディタが同時に存在する場合は、競合を避けたいと考えています。

エントリが現在どのように追加されているかを示します。

$content = file_get_contents("./file.csv"); 
$fh = fopen("./file.csv", "w"); 
fwrite($fh, $date_yy . '-' . $date_mm . '-' . $date_dd . '|' . $address . '|' . $person . '|' . $time_hh . ':' . $time_mm); 
fwrite($fh, "\n" . $content); 
fclose($fh);

どのような考えですか?

+0

私はそれを行う方法がわかりませんが、あなたがその機能を認識していない場合は、それを集めることができます。 PHP.netのマニュアルを参照してください。> http://php.net/manual/en/function.flock.php –

答えて

4

flock()関数を使用すると、ファイルをロックできます。以上のようなthis

何かを参照してください:

<?php 

     $content = file_get_contents("./file.csv"); 
     $fp = fopen("./file.csv", "w"); // open it for WRITING ("w") 
     if (flock($fp, LOCK_EX)) 
     { 
     // do your file writes here 
     fwrite($fh, $date_yy . '-' . $date_mm . '-' . $date_dd . '|' . $address . '|' . $person . '|' . $time_hh . ':' . $time_mm); 
     fwrite($fh, "\n" . $content); 
     fclose($fh); 
     flock($fh, LOCK_UN); // unlock the file 
     } 
    ?> 
+2

* fopen *と* flock *の間でファイルがゼロになります( 'w'アクセスのため)。 OPが望んでいるもの...また、ファイルを閉じる前にロックを解除する必要があります... –

+0

対象は、ファイルに新しい行を追加し、内容をリセットまたは置き換えないことです。 – Janne

+1

@Janneので、 'w'ではなく' a'アクセスを使うのがよいでしょう。 –

-1

私はちょうどそのような単純な整数か何かを使用します。

$content = file_get_contents("./file.csv"); 
    $fh = fopen("./file.csv", "w"); 
    $status = 1; 

...  

if($status == 1){ 
    fwrite($fh, $date_yy . '-' . $date_mm . '-' . $date_dd . '|' . $address . '|' . $person . '|' . $time_hh . ':' . $time_mm); 
    fwrite($fh, "\n" . $content); 
    fclose($fh); 
    $status = 0; 
    } 
else 
    echo "the file is edited by another user, please try again later."; 

これはどういう意味ですか?

+0

'$ status = 1; if($ status == 1){'私はそのアルゴリズムを理解できたと思っています –

+0

@ ring0 lol私はそれを私がそこに置いたのとまったく同じように実行することはできません。たぶん以前のか、checkStatus()関数があります。ユーザーが編集をクリックしたかどうかを追跡し、送信時に0にリセットされます。 私は上記が技術的に正しくないことを認識しました。申し訳ありません – shanehoban

2

  1. は、データベースを使用してください。
  2. 複数のテキストファイルを使用します。
  3. 使用locks

例:

$lockwait = 2;  // seconds to wait for lock 
$waittime = 250000; // microseconds to wait between lock attempts 
// 2s/250000us = 8 attempts. 
$myfile = '/path/to/file.txt'; 

if($fh = fopen($myfile, 'a')) { 
    $waitsum = 0; 
    // attempt to get exclusive, non-blocking lock 
    $locked = flock($fh, LOCK_EX | LOCK_NB); 
    while(!$locked && ($waitsum <= $lockwait)) { 
    $waitsum += $waittime/1000000; // microseconds to seconds 
    usleep($waittime); 
    $locked = flock($fh, LOCK_EX | LOCK_NB); 
    } 
    if(!$locked) { 
    echo "Could not lock $myfile for write within $lockwait seconds."; 
    } else { 
    // write out your data here 
    flock($fh, LOCK_UN); // ALWAYS unlock 
    } 
    fclose($fh);   // ALWAYS close your file handle 
} else { 
    echo "Could not open $myfile"; 
    exit 1; 
} 
1

あなたが書き込み用にファイルをロックするPHP's flock functionを使用できますが、そのロックがWeb要求間で保持されませんし、NFSマウント上では動作しません。 (少なくとも私の経験では)。

トークンファイルを同じディレクトリに作成し、その存在をチェックし、存在する場合はエラーを報告することが最善の場合があります。

どのようなロッキングスキームでも、操作が完了した後に残る競合条件とロックがあるので、それらを緩和する方法が必要です。

この値を編集してロックファイルに保存する前に、ファイルのハッシュを作成することをお勧めします。また、そのハッシュを編集フォームの一部としてクライアントに送信します(コミット要求のデータとして返されます)。書き込む前に、渡されたハッシュ値をファイルの値と比較してください。両者が同じ場合は、データをコミットしてロックを解除します。

異なる場合は、エラーを表示してください。

+0

ロックがWeb要求を超えて持続しないのはなぜですか?ロックはファイル上にあり、ディスクリプタではありません(少なくともLinuxでは) –

+0

fcloseはロックを削除するので、ロックはファイルハンドルがオープンされている間だけロックされます。私は植え付けで多くの運がなかったので、私はそれを避ける傾向があります。私はこの場合セマフォーファイルを使うのが良い解決策だと思います。なぜなら、編集が開始されたときにロックが得られ、後でいくつかのサブミット/バリデート/再サブミットができるからです。私はあなたの質問を避けようとしていない、私はちょうど良い答えを持っていない。 –

+0

いいえ、(phpのflockが実装する)flock c関数は、記述子で動作します。 http://linux.die.net/man/2/flock – symcbean

関連する問題