2

このループがブラウザーに何も返さない理由を理解しようとしています。

while(1) {
    echo "hello";
    flush();
    sleep(1);
}

毎秒「こんにちは」がブラウザに返されることを期待しています...間違っていますか? 現在、ページがハングしているようです。

4

8 に答える 8

3

PHP は、実行が終了した後にのみ出力します。そのため、どこで行っているかはミリ秒ごとに新しい hello を生成するだけであり、ループを終了することはないため、出力は表示されません。

于 2013-03-08T20:37:05.203 に答える
2

私の答えを修正し、理解を深めるために、そしてAJAX愛好家のために...そこに余分なフラッシュが必要です..「ob_」のもの:

<?php
while( 1 ):
    echo "hello";
    ob_flush( ); flush();
    sleep( 1 );
endwhile;

これは、知る必要があるすべての人のための「トリック」です ;)

于 2013-03-22T08:24:53.490 に答える
0

答えるのに遅刻することはないかもしれませんが、ここで毎秒フラッシュしたい場合は、サンプルを提供します。

<?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';
于 2013-03-22T07:00:51.067 に答える
0

わかりました、カルロスは私が私の答えを説明しなかったので私を批判しますが、彼の答えはあいまいです... 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);
}

ちゃ..

于 2013-03-22T09:58:26.667 に答える
0

ページ全体が受信されるまで、ブラウザーは何も表示しません。PHP は、あなたが達成しようとしていることに対応できません。

Javascript では、これは非常に単純です。

<script>
    window.setInterval(function(){document.innerHTML += "<br> Hello"}, 1000)
</script>
于 2013-03-08T20:36:49.170 に答える
0

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 を有効にしています。デフォルトでオフ/オンにするには、構成変数を参照してください。

于 2013-03-22T08:50:53.853 に答える
0

PHP は、スクリプトの完了後にのみ出力を返すという意味で、スクリプト言語であることを理解する必要があります。編集:または、出力バッファがいっぱいになった後、@Marc Bに感謝します。とにかく、これにはJSを使用する方が賢明だと思います。サーバーが本当に必要な場合は、AJAXリクエストを使用してください。

おそらく、Javascript の使用を検討する必要がありますか? これにより、毎秒コンテンツを追加できるようになります (ただし、JS はクライアント側で実行されることに注意してください。そのため、操作をそれほど拡張したくない場合があります)。

または、インスタンス JQuery を介して AJAX リクエストを使用することを検討することもできますが、それはこの質問の範囲外である可能性があります...

于 2013-03-08T20:39:42.080 に答える
-1

他のすべての答えに加えて、

クライアントへの非同期サーバー プッシュを行うには、WebSocket を使用する必要があります。これは広大なテーマであり、完全には標準化されていませんが、それを行う方法は確かにあります。興味がある場合は、PHP Websockets を検索してください。

于 2013-03-08T20:44:47.730 に答える