このループがブラウザーに何も返さない理由を理解しようとしています。
while(1) {
echo "hello";
flush();
sleep(1);
}
毎秒「こんにちは」がブラウザに返されることを期待しています...間違っていますか? 現在、ページがハングしているようです。
このループがブラウザーに何も返さない理由を理解しようとしています。
while(1) {
echo "hello";
flush();
sleep(1);
}
毎秒「こんにちは」がブラウザに返されることを期待しています...間違っていますか? 現在、ページがハングしているようです。
PHP は、実行が終了した後にのみ出力します。そのため、どこで行っているかはミリ秒ごとに新しい hello を生成するだけであり、ループを終了することはないため、出力は表示されません。
私の答えを修正し、理解を深めるために、そしてAJAX愛好家のために...そこに余分なフラッシュが必要です..「ob_」のもの:
<?php
while( 1 ):
echo "hello";
ob_flush( ); flush();
sleep( 1 );
endwhile;
これは、知る必要があるすべての人のための「トリック」です ;)
答えるのに遅刻することはないかもしれませんが、ここで毎秒フラッシュしたい場合は、サンプルを提供します。
<?php
echo "Flushing every second ...\n";
flush( );
$seconds = array (0,1,2,3,4,5,6,7,8,9);
foreach ($seconds as $second):
echo $second . "\n";
sleep( 1 );
@ob_flush( ); flush( );
endforeach;
echo 'I flashed 10 second :P';
わかりました、カルロスは私が私の答えを説明しなかったので私を批判しますが、彼の答えはあいまいです... Cookie、レイヤー.. POST、ob_levels ... :OOの本当の問題についての本当の意味のない多くの情報ユーザーですが、コードが機能しない理由を説明します。php.ini で出力バッファリングを次のように設定したためです。
output_buffering = On
また
output_buffering = 4096 (default setting on most distributions)
そのため、ガベージ出力を取り除くために、追加の「ob_flush()」が必要です。
そう...コードを機能させるには、2つのオプションがあります。
1). set output_buffering = 0 or Off (if you have access to the php.ini)
2). ob_flush many times as layers of buffering you have
レイヤーの数がわからない場合は、次のようにすることができます。
while (@ob_end_clean( ));
そして、あなたが持つことができるすべてのゴミをきれいにしてください.そうすれば、あなたのコードはうまく動作します..完全なスニップ:
<?php
while (@ob_end_clean( ));
while(1) {
echo "hello";
flush();
sleep(1);
}
ちゃ..
ページ全体が受信されるまで、ブラウザーは何も表示しません。PHP は、あなたが達成しようとしていることに対応できません。
Javascript では、これは非常に単純です。
<script>
window.setInterval(function(){document.innerHTML += "<br> Hello"}, 1000)
</script>
Valentinはあなたに正しい答えを与えました (彼に賛成票を投じる/彼の答えを受け入れます!) が、その理由は説明しませんでした。説明は次のとおりです。
PHP はすぐにブラウザーに出力せず、ブラウザーに送信するコンテンツの量を待つ (おそらく 1024、2048、または 4096 バイトのチャンクで送信する) か、実行が終了したときです。呼び出しflush()
により、PHP はデータを送信しますが、バッファリングには複数の層があります。1 つは内部バッファリング (先ほどコメントしたもの) ですが、バッファリングのレイヤーをさらに追加できます。次のコードを想定します。
<?php
echo "hi";
setcookie('mycookie', 'somevalue');
?>
このsetcookie()
関数は http ヘッダーをブラウザーに送信しますが、HTTP ではサーバー (またはクライアント、どちらの方法でも同じです) が最初にすべてのヘッダー、空白行、次にコンテンツを送信する必要があるため、これを行うことはできません。ご覧のとおり、ヘッダーの前にコンテンツ ( hi ) を出力しているため、失敗します (内部バッファリングが同じ実行順序に従うため)。
php functions を使用して、出力バッファリングの別のレイヤーを追加できますob_*()
。バッファリングでは、HTTP ヘッダーではなく、コンテンツ出力のみをob
バッファリングします。また、これらを使用して、ブラウザに直接出力する関数の出力を取得できますvar_dump()
。また、次のレイヤーをネストできますob
。
<?php
// start first level of output buffering
ob_start();
echo "nesting at level ", ob_get_level(), "<br />\n"; // prints level 1
echo "hi<br />";
ob_start();
echo "nesting at level ", ob_get_level(), "<br />\n"; // prints level 2
var_dump($_POST);
$post_dump = ob_get_clean();
// this will print level 1, because ob_get_clean has finished one level.
echo "nesting at level ", ob_get_level(), "<br />\n";
echo "The output of var_dump(\$_POST) is $post_dump<br />\n";
// in spite of being inside a layer of output_buffering, this will work
setcookie('mycookie', 'somevalue');
// flush the current buffer and delete it (will be done automatically at the
// end of the script if not called explicitly)
ob_end_flush();
おそらく、あなたの PHP サーバーはデフォルトで output_buffering を有効にしています。デフォルトでオフ/オンにするには、構成変数を参照してください。
PHP は、スクリプトの完了後にのみ出力を返すという意味で、スクリプト言語であることを理解する必要があります。編集:または、出力バッファがいっぱいになった後、@Marc Bに感謝します。とにかく、これにはJSを使用する方が賢明だと思います。サーバーが本当に必要な場合は、AJAXリクエストを使用してください。
おそらく、Javascript の使用を検討する必要がありますか? これにより、毎秒コンテンツを追加できるようになります (ただし、JS はクライアント側で実行されることに注意してください。そのため、操作をそれほど拡張したくない場合があります)。
または、インスタンス JQuery を介して AJAX リクエストを使用することを検討することもできますが、それはこの質問の範囲外である可能性があります...
他のすべての答えに加えて、
クライアントへの非同期サーバー プッシュを行うには、WebSocket を使用する必要があります。これは広大なテーマであり、完全には標準化されていませんが、それを行う方法は確かにあります。興味がある場合は、PHP Websockets を検索してください。