長い PHP スクリプトを実行し、HTTP 経由でブラウザーに更新を送信し続けるにはどうすればよいでしょうか?
出力バッファリングと関係がありますが、正確な方法はわかりません。
出力バッファリングは正しい方向に考えています。出力が送信される前に、スクリプトの先頭のどこかでob_start()
セッション () と同じように出力バッファリングを開始します。session_start
次に、 and を使用ob_flush
しflush
て、出力をフラッシュし続けることができます。たとえば、foreach
ループ内にいて、各ループの最後に新しい行を出力して 1 秒待機する場合は、それを行うことができます。
ただし、 も参照してくださいset_time_limit
。そうしないと、30 秒ほどでタイムアウトが発生する可能性があります。
別の簡単な注意として、一部のブラウザーでは、実際に表示を開始する前に、出力の最小バイト数が必要です。バイト数はわかりませんが、4000 前後だったと思います。また、一部のブラウザーは、特定の要素 (テーブルなど) を閉じるまでレンダリングしません。そのため、フラッシングもそこでは機能しません。
これはあなたが求めているもののように見えます:
出力バッファリングにより、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 がスクリプトの最後に到達すると、開いている出力バッファーを自動的にフラッシュするためです。
単純なHTTP出力を使用してページを更新し、機能させるようにしました。
<body>
いない場合は表示されません。<p>
)で囲みますこれが私のコードです:
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();
}
<?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
}
?>
また、一種のバックグラウンド タスクと、進行率を示すインターフェイスを使用することもできます。
たとえば、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 の更新を行います。「大きな」ファイルをアップロードするためのそのような方法を見たことがありますが、それは素晴らしいと思いました。
編集:申し訳ありませんが、これは最初の質問に正確には答えていません。