奇怪的 PHP 输出缓冲

奇怪的 PHP 输出缓冲

PHP的:

header('Content-type: text/plain');

for ($i=0; $i<10; $i++){
  echo "$i\r\n";
  ob_flush();
  flush();
  sleep(1);
}

我在 2 个不同的服务器上尝试了上述脚本。两台服务器的每一行都响应数字 0...9。对于第一台服务器,每秒都会收到每个数字。对于第二台服务器,10 秒内没有输出,并且一次显示整个输出。第二种情况可能出了什么问题?我尝试了各种输出控制函数,但没有帮助。

两种情况下的响应标头设置几乎相同:

HTTP/1.1 200 OK
Date: Mon, 03 Jan 2011 19:21:21 GMT
Server: Apache
X-Powered-By: PHP/5.2.14
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/plain

答案1

您需要在 php.ini 中将 output_buffering 设置为“Off”,然后重新启动 apache,output_buffering 的默认值为 4096,这会阻止 ob_flush() 和 flush() 生效。您的示例代码开头还缺少 ob_start();。

输出缓冲 = 关闭

答案2

可以在运行时调用输出缓冲或者默认启用(如第二台服务器的情况)。

运行<?php var_dump( ini_get('output_buffering') ); ?><?php phpinfo(); ?>查看它是否在您使用的服务器上启用。

参考: PHP 手册

答案3

PHP 何时刷新缓冲区与 Web 服务器决定何时写入输出关系不大 - Web 服务器可能会推送部分响应(相对不常见)或分块响应(如您的情况)。Web 服务器不提供直接控制输出流的功能。它们也不应该提供。在 PHP 中使用输出缓冲只是稍微推迟了分块。

如果您想在代码仍在运行时在浏览器上产生输出,这不是实现它的方法 - 分叉一个单独的进程(最好在新的会话组中)并向浏览器写入存根响应 - 然后使用 Ajax 将更新发送到存根(可选使用长轮询)。

相关内容