2012-02-05 9 views
17

PHPを使用して、大きなファイルを読み込み、要求されたときに現在の行番号を送信するwhileループを作成したいと考えています。 Ajaxを使用して、現在の行数を取得してページに出力したいと思います。 htmlボタンを使用すると、1回だけ実行されるjavascriptスレッドをクリックしてアクティブ化または終了し、ajaxメソッドを呼び出すことができます。PHP - LoopデータをAjaxでフラッシュする

私はそれに打撃を与えているが、何らかの理由で、それはコメントアウトだとき、私はecho str_repeat(' ',1024*64);機能をコメントアウトしない限り、何も印刷は、それがループ全体の結果を示しています。

1行(複数可)processed.2行を処理された行3行4行5行6行6行7行8行9処理9行s)が処理されました.10行が処理されました。代わりに別の行にそれらを示すの一行で

が好き:

1 row(s) processed. 
2 row(s) processed. 
3 row(s) processed. 
4 row(s) processed. 
5 row(s) processed. 
6 row(s) processed. 
7 row(s) processed. 
8 row(s) processed. 
9 row(s) processed. 
10 row(s) processed. 

また、私はJavaScriptのスレッドを終了するかどうかはわかりません。合計で2つの問題:

1. It's returning the entire While loop object at once instead of each time it loops. 
2. I'm not sure how to terminate the JQuery thread. 

アイデアをお持ちですか?以下は私のコードです。

msgserv.php

<?php 

//Initiate Line Count 
$lineCount = 0; 

// Set current filename 
$file = "test.txt"; 

// Open the file for reading 
$handle = fopen($file, "r"); 

//Change Execution Time to 8 Hours 
ini_set('max_execution_time', 28800); 

// Loop through the file until you reach the last line 
while (!feof($handle)) { 

    // Read a line 
    $line = fgets($handle); 

    // Increment the counter 
    $lineCount++; 

    // Javascript for updating the progress bar and information 
    echo $lineCount . " row(s) processed."; 

    // This is for the buffer achieve the minimum size in order to flush data 
    //echo str_repeat(' ',1024*64); 

    // Send output to browser immediately 
    flush(); 

    // Sleep one second so we can see the delay 
    //usleep(100); 
} 

// Release the file for access 
fclose($handle); 

?> 

asd.html

<html> 
    <head> 
     <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript" charset="utf-8"></script> 

     <style type="text/css" media="screen"> 
      .msg{ background:#aaa;padding:.2em; border-bottom:1px #000 solid} 
      .new{ background-color:#3B9957;} 
      .error{ background-color:#992E36;} 
     </style> 

    </head> 
    <body> 

    <center> 
     <fieldset> 
      <legend>Count lines in a file</legend> 
      <input type="button" value="Start Counting" id="startCounting" /> 
      <input type="button" value="Stop Counting!" onclick="clearInterval(not-Sure-How-To-Reference-Jquery-Thread);" /> 
     </fieldset> 
    </center> 

    <div id="messages"> 
     <div class="msg old"></div> 
    </div> 

    <script type="text/javascript" charset="utf-8"> 
     function addmsg(type, msg){ 
      /* Simple helper to add a div. 
     type is the name of a CSS class (old/new/error). 
     msg is the contents of the div */ 
      $("#messages").append(
      "<div class='msg "+ type +"'>"+ msg +"</div>" 
     ); 
     } 

     function waitForMsg(){ 
      /* This requests the url "msgsrv.php" 
     When it complete (or errors)*/ 
      $.ajax({ 
       type: "GET", 
       url: "msgsrv.php", 
       async: true, /* If set to non-async, browser shows page as "Loading.."*/ 
       cache: false, 
       timeout:2880000, /* Timeout in ms set to 8 hours */ 

       success: function(data){ /* called when request to barge.php completes */ 
        addmsg("new", data); /* Add response to a .msg div (with the "new" class)*/ 
        setTimeout(
        'waitForMsg()', /* Request next message */ 
        1000 /* ..after 1 seconds */ 
       ); 
       }, 
       error: function(XMLHttpRequest, textStatus, errorThrown){ 
        addmsg("error", textStatus + " (" + errorThrown + ")"); 
        setTimeout(
        'waitForMsg()', /* Try again after.. */ 
        "15000"); /* milliseconds (15seconds) */ 
       }, 
      }); 
     }; 

     $('#startCounting').click(function() { 
      waitForMsg(); 
     }); 
    </script> 

</body> 
</html> 

試験。使用

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 

答えて

8

TXT:

を使用すると、1つのPHPのスレッドで必要なすべてを行う必要があります

EDIT

アルゴリズムあなたがこれを行うにはどのような方法を探しているなら、単にそれは、次のことだろう、nickbの答えを見てみましょう:やるであろう(AJAX経由process.phpを開き、JavaScriptの

  1. ユーザーがリフレッシュを停止することを決定した場合、すべての作業や印刷ステータスレポート)は、あなたが提供されたリンクでのショーなどの負荷を殺すjQueryのAjaxは、連続読み込み
  2. をサポートしているかどうかをルックアップする必要があり
process.php

ignore_user_abort(); // Script will finish in background 
while(...){ 
    echo "Page: $i\n"; 
    ob_flush(); 
} 

EDIT 2は、例えば(異なると醜い、単純なビット)を要求しました。 test_process.php

// This script will write numbers from 1 to 100 into file (whatever happens) 
// And sends continuously info to user 
$fp = fopen('/tmp/output.txt', 'w') or die('Failed to open'); 
set_time_limit(120); 
ignore_user_abort(true); 

for($i = 0; $i < 100; $i++){ 
    echo "<script type=\"text/javascript\">parent.document.getElementById('foo').innerHTML += 'Line $i<br />';</script>"; 
    echo str_repeat(' ', 2048); 
    flush(); 
    ob_flush(); 
    sleep(1); 
    fwrite($fp, "$i\n"); 
} 

fclose($fp); 

そして、メインのHTMLページ:divの#fooに登場

Line 1 
Line 2 

<iframe id="loadarea"></iframe><br /> 
<script> 
function helper() { 
    document.getElementById('loadarea').src = 'test_process.php'; 
} 
function kill() { 
    document.getElementById('loadarea').src = ''; 
} 
</script> 

<input type="button" onclick="helper()" value="Start"> 
<input type="button" onclick="kill()" value="Stop"> 
<div id="foo"></div> 

としてスタートラインを打った後。私がStopを押すと、それらは表示されなくなりましたが、スクリプトはバックグラウンドで終了し、すべての100の数字をファイルに書きました。

Startをもう一度押すと、スクリプトが募集(ファイルの書き換え)から実行を開始し、パラレルリクエストが実行されます。 HTTPストリーミングの詳細については

はあなたがPHPとAJAXがどのように相互作用するかのように混乱しているthis link

+0

こんにちは、ありがとうございました。私はあなたの提案を試みたが、どれも私のために働いていない。私が提供した3つのファイルを保存して、あなたのために働くかどうか教えてください。もしそうなら、あなたが見つけたものを分かち合うことができますか? – ThreaT

+0

@ user1191027 read編集 – Vyktor

+0

もう一度、ありがとう - あなたの新しい提案を試みたがまだ運がありません...彼らはあなたのために働いたのですか? – ThreaT

11

を参照してください。

PHPページをAJAX経由でリクエストすると、PHPスクリプトの実行を強制します。内部PHPバッファをクリアするのにflush()を使用しているかもしれませんが、ファイル全体が読み込まれたときに接続が閉じられるまで、AJAX呼び出しは終了しません(つまり、応答ハンドラは呼び出されません)。最初のAJAXポストは、ファイルの読み込みを開始する要求を送信し

  1. :あなたが探しているものを達成するために

    は、私はあなたがこのような並列処理の流れを必要とするだろうと信じています。このスクリプトは、いくつかのunqiue IDを生成し、それをブラウザに送り返し、実際にファイルを読み取ったスレッドを生成して終了します。

  2. その後のすべてのAJAXリクエストは、ファイル読み込みのステータスをチェックする別のPHPスクリプトに送られます。この新しいPHPスクリプトは、#1で生成された一意のIDに基づいて、ファイル読み取りの現在のステータスを送信して終了します。

このプロセス間通信は、$_SESSION個の変数を使用して行うことも、データをデータベースに格納することもできます。いずれにしても、現在のシーケンシャル実装ではなく、パラレル実装が必要です。そうしないと、ステータス全体を一度に取得できます。

+0

こんにちは、ありがとうございました。私はあなたの提案を試みたが、どれも私のために働いていない。私が提供した3つのファイルを保存して、あなたのために働くかどうか教えてください。もしそうなら、あなたが見つけたものを分かち合うことができますか? – ThreaT

0

トリックはファイル(Ajax経由で更新)を作成し、setIntervalを使用してその値を取得し、次にプログレスバーを更新することです。

+0

提供されたURLはもう機能しません – mattspain

+0

単にリンクするのではなく、答えの中にコンテンツを投稿する必要がある理由の例です。 –

+0

完全に理解されています。私は今からその代わりにやっていきます。 –