2013-02-22 16 views
6

大量のレコードを送信するPHPスクリプトがあり、使用できるようになるとすぐに各レコードをフラッシュしたい:クライアントは到着時に各レコードを処理できる応答全体を待つ必要はありません。私はそれが複数のパケットで送られる必要があるので、転送全体のためにわずかに時間がかかることに気づいていますが、依然としてクライアントはより早く作業を開始できます。PHPとApacheでの出力バッファリングの防止

flush()ob_flush()の機能をすべて試しましたが、ページが完成する前に実際にデータを送信するのに役立つものはありません。 Telnetを使ってテストしたので、Webブラウザではないことを確認しました。

答えて

4

唯一の解決策は、php.iniのoutput_bufferingディレクティブを "オフ"に設定することでした。私はサーバー全体でこれをやりたいとは思っていませんでした。通常はini_setをPHPスクリプトから使用できますが、何らかの理由でPHPではoutput_bufferingをこのように設定することはできません(the php manual参照)。

Apacheを使用している場合は、.htaccessファイルを含め、サーバの設定からphp iniディレクティブ(output_bufferingを含む)を設定することができます。だから、僕はその1つのファイルのためにoutput_bufferingを無効にするには、.htaccessファイルに次のように使用:

<Files "q.php"> 
    php_value output_buffering Off 
</Files> 

そして、私の静的なサーバ構成で、私はちょうど(AllowOverride Allのように、またはより大きなハンマー)AllowOverride Options=php_valueを必要とためにそれが.htaccessファイルで許可されるためです。

+1

PHP5.6でこれが間違っていたり、何かが変更されているかどうかはわかりませんが、 'php_flag output_buffering Off'を使って' Off'を動作させなければなりませんでした。 – RiggsFolly

+0

php.iniの "output_buffering"を4096からOffに設定し、サーバ全体を再起動し、phpinfo()で検証しました。私はまだ同じ問題に直面している、サーバーはブラウザにデータを送信する前にページの読み込みを待っています。 Apache2またはUbuntu 16.04に別の設定がありますか?私はPHP7を使用しています。 – Tarik

3

使用しているWebサーバーについては言及していませんが、私はここに足を運んでApache2を推測します。私は、あなたが描写したものとほぼ同じことを打ちました。私は、すべてをバッファリングするのではなく、準備が整ったときに情報を返すようにCGIスクリプトを作成しようとしていました。カールなどで作業していましたが、ブラウザにバッファリングされていました。ほとんどのブラウザでは、少なくとも怒っていました。私はあなたが描いている正確な手順を行った。私の場合、解像度はApache2の中sites-enabled/terrifico.com設定ファイルを変更する(問題のラインは

で始まりました(あなたはそのラインの上および下のものを無視することができ、私はちょうど示すよ

をSetEnvIfNoCase私はそれを置く場所の参照のためのそれ。)

<VirtualHost *:80> 
ServerAdmin [email protected] 
ServerName test.terrifico.com 
ServerAlias test.terrifico.com 

SetEnvIfNoCase Request_URI \.cgi$ no-gzip dont-vary 

DocumentRoot /var/www/test.terrifico.com 

前後に行くのネットワークトラフィックを見つめから、それは最終的には、ブラウザはそれが何のためにデフレを受け入れたことを宣伝していることを私に夜が明けた(つまり、テキストでした)。それは例えばブラウザとカールの違いでした。顕著なビットだっ

受け入れエンコード:gzipで、収縮させる、SDCH

ありビット程度chunkingだったが、それは、この特定の問題に影響を与えませんでした。だから、ブラウザはmod_deflateが私のCGIスクリプトで取得したように慎重に吐き出すバイトを打ち負かすことを要求していました。あなたはブラウザでそれを変更することができましたが、作品のために一度それをサーバー上で変更する方が賢明だったようです。

これはおそらく役立ちます。

2

だけで、スクリプトの先頭でob_end_flush()またはob_end_clean()を使用し、php.iniを変更したり、.htaccessファイルがなくても、PHPでの実行時に出力バッファリングをオフにします。例えば:

このすべきバッファリングせずに出力:

<?php 
ob_end_clean(); 

for ($i = 0; $i < 5; $i++) 
{ 
    echo "$i\n"; 
    flush(); 
    usleep(0.5e6); 
} 

これは、(一度にすべて)バッファと出力output_bufferingに関係なくflush()コールの上にある場合:にもかかわらず

<?php 

for ($i = 0; $i < 5; $i++) 
{ 
    echo "$i\n"; 
    flush(); 
    usleep(0.5e6); 
} 

そのob_implicit_flushは、すべての出力後に暗黙的にflush()ではなく、ob_flush()を呼び出します。これは、最初に出力バッファを閉じた後のこのインスタンスでは便利です:

<?php 
ob_end_clean(); // disable output buffer 
ob_implicit_flush(); // call flush() automatically after every output 

for ($i = 0; $i < 5; $i++) 
{ 
    echo "$i\n"; 
    usleep(0.5e6); 
} 

これはPHP側を修正しています。 mod_deflateなど(テッド・コリンズの答えを参照)で何か他のことが起こっている可能性があります。何かを出力する前に少なくとも1024バイト必要です。

+0

このコードは同じ3倍の-.- –

関連する問題