给mod_fcgid用户的注意事项(请使用,后果自负)。
快速解决方案
Joeri Sebrechts的公认答案确实有用。但是,如果使用mod_fcgid,则可能会发现此解决方案无法单独使用。换句话说,调用flush函数时,与客户端的连接不会关闭。
可能要怪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网页中的升级说明)。
细节和第二个解决方案
上述解决方案禁用了mod_fcgid对整个服务器或特定虚拟主机执行的缓冲。这可能会导致您的网站性能下降。另一方面,情况可能并非如此,因为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的缓冲区,从而迫使其刷新。选择数字“ 65537”是因为FcgidOutputBufferSize
变量的默认值是“ 65536”,如相应指令的Apache Web页面中所述。因此,如果您的环境中设置了另一个值,则可能需要相应地调整此值。
我的环境
- WampServer 2.5
- 阿帕奇2.4.9
- PHP 5.5.19 VC11,x86,非线程安全
- mod_fcgid / 2.3.9
- Windows 7专业版x64
虚拟主机示例
<VirtualHost *:80>
DocumentRoot "d:/wamp/www/example"
ServerName example.local
FcgidOutputBufferSize 0
<Directory "d:/wamp/www/example">
Require all granted
</Directory>
</VirtualHost>