6

長い PHP スクリプトを実行し、HTTP 経由でブラウザーに更新を送信し続けるにはどうすればよいでしょうか?

出力バッファリングと関係がありますが、正確な方法はわかりません。

4

5 に答える 5

3

出力バッファリングは正しい方向に考えています。出力が送信される前に、スクリプトの先頭のどこかでob_start()セッション () と同じように出力バッファリングを開始します。session_start

次に、 and を使用ob_flushflushて、出力をフラッシュし続けることができます。たとえば、foreachループ内にいて、各ループの最後に新しい行を出力して 1 秒待機する場合は、それを行うことができます。

ただし、 も参照してくださいset_time_limit。そうしないと、30 秒ほどでタイムアウトが発生する可能性があります。

別の簡単な注意として、一部のブラウザーでは、実際に表示を開始する前に、出力の最小バイト数が必要です。バイト数はわかりませんが、4000 前後だったと思います。また、一部のブラウザーは、特定の要素 (テーブルなど) を閉じるまでレンダリングしません。そのため、フラッシングもそこでは機能しません。

于 2010-06-08T09:30:18.390 に答える
2

これはあなたが求めているもののように見えます:

出力バッファリングにより、PHP はスクリプトの出力を、準備が整うとすぐに Web サーバーに送信します。これは、行単位またはコード ブロック単位で行われます。

出力バッファリング

ob_start() 関数は、新しい出力バッファを作成するために使用され、通常どおりコンテンツを出力することですぐに書き込みを開始できます。バッファを開いたら、ob_end_flush() と ob_end_clean() の 2 つの方法で閉じることができます。どちらもバッファを終了しますが、その方法は少し異なります。前者はバッファーを終了し、すべてのデータを出力に送信します。後者は、出力に送信せずにバッファーを終了し、そこに保存した情報を効果的に消去します。出力バッファが開いている間に出力されるすべてのテキストは、出力に送信されるのではなく、そのバッファに配置されます。次のスクリプトを検討してください。

<?php
  ob_start();
  print "In first buffer!\n";
  ob_end_flush();
  ob_start();
  print "In second buffer!\n";
  ob_end_clean();
  ob_start();
  print "In third buffer!\n";
?>

最初のテキストがバッファに配置され、ob_end_flush() でフラッシュされるため、そのスクリプトは「In first buffer」を出力します。ただし、「In second buffer」は出力されません。これは、ob_end_clean() を使用して消去され、出力に送信されないバッファーに配置されるためです。最後に、スクリプトは「In third buffer」と出力します。これは、PHP がスクリプトの最後に到達すると、開いている出力バッファーを自動的にフラッシュするためです。

于 2010-06-08T09:27:53.527 に答える
1

単純なHTTP出力を使用してページを更新し、機能させるようにしました。

  • 開いている要素をすべて閉じていることを確認してください。閉じて<body>いない場合は表示されません。
  • 出力されたテキストを要素(など<p>)で囲みます
  • 出力バッファリングと通常のフラッシングを使用する
  • Firefox3でテスト済み

これが私のコードです:

for ($nc=0; $nc<10; $nc++){

    // delay just to test
    sleep(1);

    // send message to browser
    ob_end_clean();
    ob_start();
    echo "<p>Update ".$nc."</p>";
    ob_end_flush();
    flush();
}
于 2010-06-08T09:48:27.183 に答える
1
<?php
# try this...
for (;;) {
  echo time() . '<br>';
  ob_flush(); # http://php.net/ob_flush
  flush(); # http://php.net/flush
  sleep(1); # http://php.net/sleep
}
?>
于 2010-06-08T09:38:56.073 に答える
1

また、一種のバックグラウンド タスクと、進行率を示すインターフェイスを使用することもできます。

たとえば、job.php というページ

<?php
    for ($i=0; $i<100; ++$i)
    {
       store($i);
       // long stuff
       sleep(42);
    }
?>

そしてprogress.php

<?php
      return get($i);
?>

次に、progress.php?task=mytaskid へのいくつかの ajax 呼び出しと GUI の更新を行います。「大きな」ファイルをアップロードするためのそのような方法を見たことがありますが、それは素晴らしいと思いました。

編集:申し訳ありませんが、これは最初の質問に正確には答えていません。

于 2010-06-08T09:32:13.597 に答える