PHPのブラウザ出力のタイミングについての質問です。

以下のように1行ずつ出力させるプログラムを考えます。
for ($i = 0; $i < 100; $i++) {
print $i . "<BR>\n";
sleep(1);
}
このプログラムをサーバーにおき、ブラウザからアクセスすると、サーバー環境により1行ずつ表示される場合と全行がまとめて表示される場合があります。
PHPかWebサーバー(Apacheを前提)側の制御によるものと思っております。
(ブラウザ機能としての制限は今回は考えないでいいです)
プログラムの先頭にob_end_flush()とか入れても変わりませんでした。
この出力タイミングの制御について、出力タイミングを随時にする方法、最後にまとめて出力する方法に関する設定をお教え頂きたいです。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2011/01/25 13:22:05
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:rouge_2008 No.3

回答回数595ベストアンサー獲得回数351

ポイント27pt

「ob_flush()」および「flush()」なしで、「print $i . "<BR>\n";」だけで1行ずつ出力されるサーバーと最後にまとめて出力されるサーバーがあるのですか?

php.iniの次の設定を確認してみてください。

まとめて出力されるサーバーの設定が「Off」になっているのではないかと思います。

implicit_flush = Off

php.iniが触れない場合は、.htaccessで設定する事も出来ます。

php_flag implicit_flush On

http://www.php.net/manual/ja/outcontrol.configuration.php

http://www.asahi-net.or.jp/~wv7y-kmr/note/2004-01.html#YMD200401...

ただ、負荷が掛かる為あまり推奨されていないようです。

どうしても自動的にフラッシュしたい場合は、該当するスクリプトに直接記述した方が良いと思います。

while ( ob_get_level() ) {
    ob_end_flush();
}
ob_implicit_flush();

// IE、Webkit等のブラウザ対策
for($i = 0; $i < 1024; $i++) {
    echo " ";
}

for ($i = 0; $i < 100; $i++) {
    print $i . "<BR>\n";
    sleep(1);
}

http://www.php.net/manual/ja/function.ob-implicit-flush.php

id:nakamuraaaaa

上記設定をいろいろ触ってみましたが、どうも出力については制御できませんでした。

実装したいというよりは、技術的にどこの設定をいじると制御できるのかを知りたかったので、もう少しApache・PHPの設定レベルで確認してみようと思います。

2011/01/25 13:20:03

その他の回答2件)

id:deflation No.1

回答回数1036ベストアンサー獲得回数126

ポイント27pt

ループを回る度に出力する方法

<?php
ob_start();
for ($i = 0; $i < 100; $i++) {
    print $i . "<BR>\n";
    ob_flush();
    flush();
    sleep(1);
}
ob_end_clean();
?>

ループを抜けた後に出力する方法

<?php
ob_start();
for ($i = 0; $i < 100; $i++) {
    print $i . "<BR>\n";
    sleep(1);
}
ob_flush();
flush();
ob_end_clean();
?>

または

<?php
$outstr = '';
for ($i = 0; $i < 100; $i++) {
    $outstr .= $i . "<BR>\n";
    sleep(1);
}
print $outstr;
?>
id:nakamuraaaaa

ご回答ありがとうございます。

上記は質問前に確認済みですがだめでした。

したがってPHP設定レベルかApache設定レベルの制御かなと考えております。

2011/01/20 10:18:01
id:la-la-land No.2

回答回数58ベストアンサー獲得回数6

ポイント26pt

ブラウザから見たらどうしても一度の出力になるんじゃないでしょうか。シェル上でプログラムを実行すれば1行づつの出力も可能だと思いますが。


ブラウザから見たとき1行づつ表示したいならJavascriptで実装を考えます。

id:nakamuraaaaa

少なくともさくらインターネット共用サーバのスタンダードプラン、VPSプランで構築した環境では出力と同時に表示される現象が確認され、hetemlで構築した環境では出力をまとめて吐き出されることは確認済みなので、現象自体は発生しています。

Ajax使って実装すれば簡単に実現できることはわかっているのですが、このような現象はどこの設定で変わってくるのかがどうしてもわからなかったので確認させて頂いております。

2011/01/25 13:18:02
id:rouge_2008 No.3

回答回数595ベストアンサー獲得回数351ここでベストアンサー

ポイント27pt

「ob_flush()」および「flush()」なしで、「print $i . "<BR>\n";」だけで1行ずつ出力されるサーバーと最後にまとめて出力されるサーバーがあるのですか?

php.iniの次の設定を確認してみてください。

まとめて出力されるサーバーの設定が「Off」になっているのではないかと思います。

implicit_flush = Off

php.iniが触れない場合は、.htaccessで設定する事も出来ます。

php_flag implicit_flush On

http://www.php.net/manual/ja/outcontrol.configuration.php

http://www.asahi-net.or.jp/~wv7y-kmr/note/2004-01.html#YMD200401...

ただ、負荷が掛かる為あまり推奨されていないようです。

どうしても自動的にフラッシュしたい場合は、該当するスクリプトに直接記述した方が良いと思います。

while ( ob_get_level() ) {
    ob_end_flush();
}
ob_implicit_flush();

// IE、Webkit等のブラウザ対策
for($i = 0; $i < 1024; $i++) {
    echo " ";
}

for ($i = 0; $i < 100; $i++) {
    print $i . "<BR>\n";
    sleep(1);
}

http://www.php.net/manual/ja/function.ob-implicit-flush.php

id:nakamuraaaaa

上記設定をいろいろ触ってみましたが、どうも出力については制御できませんでした。

実装したいというよりは、技術的にどこの設定をいじると制御できるのかを知りたかったので、もう少しApache・PHPの設定レベルで確認してみようと思います。

2011/01/25 13:20:03

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません