mod_fcgidユーザー向けの注意(自己責任で使用してください)。
迅速な解決策
Joeri Sebrechtsの受け入れられた答えは確かに機能的です。ただし、mod_fcgidを使用すると、このソリューションが単独では機能しない場合があります。つまり、フラッシュ関数が呼び出されても、クライアントへの接続は閉じられません。
mod_fcgidのFcgidOutputBufferSize
構成パラメーターが原因である可能性があります。私はこのヒントを見つけました:
- Travers Carterのこの返信と
- Seumas Mackinnonのこのブログ投稿。
上記を読んだ後、簡単な解決策は行を追加することであるという結論に達するかもしれません(最後の「仮想ホストの例」を参照してください):
FcgidOutputBufferSize 0
Apache構成ファイル(httpd.confなど)、FCGI構成ファイル(fcgid.confなど)、または仮想ホストファイル(httpd-vhosts.confなど)のいずれかにあります。
上記(1)では、「OutputBufferSize」という変数について言及しています。これは、FcgidOutputBufferSize
(2)で述べた古い名前です(mod_fcgidについては、Apache Webページのアップグレードノートを参照してください)。
詳細と2番目のソリューション
上記のソリューションは、サーバー全体または特定の仮想ホストに対してmod_fcgidによって実行されるバッファリングを無効にします。これにより、Webサイトのパフォーマンスが低下する可能性があります。一方、PHPは独自にバッファリングを実行するため、これは当てはまらない場合があります。
mod_fcgidのバッファリングを無効にしたくない場合は、別の解決策があります... このバッファを強制的にフラッシュできます。
以下のコードは、Joeri Sebrechtsによって提案されたソリューションに基づいて構築されています。
<?php
ob_end_clean();
header("Connection: close");
ignore_user_abort(true); // just to be safe
ob_start();
echo('Text the user will see');
echo(str_repeat(' ', 65537)); // [+] Line added: Fill up mod_fcgi's buffer.
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush(); // Strange behaviour, will not work
flush(); // Unless both are called !
// Do processing here
sleep(30);
echo('Text user will never see');
?>
追加されたコード行が本質的に行うことは、mod_fcgiのバッファーをいっぱいにして、強制的にフラッシュすることです。対応するディレクティブのApache Webページで説明FcgidOutputBufferSize
されているように、変数のデフォルト値は「65536」であるため、数値「65537」が選択されました。したがって、環境で別の値が設定されている場合は、それに応じてこの値を調整する必要がある場合があります。
私の環境
- WampServer 2.5
- Apache 2.4.9
- PHP 5.5.19 VC11、x86、非スレッドセーフ
- mod_fcgid / 2.3.9
- Windows 7 Professional x64
仮想ホストの例
<VirtualHost *:80>
DocumentRoot "d:/wamp/www/example"
ServerName example.local
FcgidOutputBufferSize 0
<Directory "d:/wamp/www/example">
Require all granted
</Directory>
</VirtualHost>