如何在共享Linux主机上禁用PHP中的输出缓冲


How can I disable output buffering in PHP on shared Linux hosting?

我刚把我的网站移到GoDaddy托管,一切都正常了,但PHP脚本不会立即输出数据——它们会缓冲,直到脚本运行完毕,然后一次呈现整个页面。显然,对于长脚本来说,这是个问题。我的老主人以前不这么做,GoDaddy的支持者说他们对此无能为力。以下是我已经尝试过的(没有成功)

  1. 禁用输出压缩(zlib、gzip)
  2. 在php.ini中设置output_buffering = off
  3. 设置Cache-Control "max-age=0, no-cache, no-store, must-revalidate"Pragma "no-cache"Expires "Wed, 10 May 1985 09:00:00 GMT"的标头,并取消设置ETag标头
  4. 我还尝试在脚本本身中设置缓冲值,使用ini_set('output_buffering', 'off')ini_set('zlib.output_compression', false)while (@ob_end_flush())ini_set('implicit_flush', true)ob_implicit_flush(true)
  5. 我尝试在每次echo输出后运行flush()ob_flush()命令
  6. 尝试将PHP版本从默认版本(5.4本机版本,已启用APC)更改为5.4非本机版本和5.5

我还创建了一个测试脚本,它只循环5次迭代,每次迭代都输出一行,然后在下一次迭代前等待一秒钟。我这样做是为了消除任何其他可能导致问题的原因。但无论我做什么,脚本总是等到它完成后才开始渲染。

那么,我能做些什么让它正常工作吗?

首先要注意的是,如果您成功地禁用了所有缓冲,您将使较短的脚本变得更慢。此外,逐步将HTML刷新到浏览器不会自动导致内容在浏览器上被呈现;您可能已经成功绕过缓冲服务器端,却发现它仍在浏览器中进行缓冲。试着用数据包嗅探器监测流量,看看是否是这种情况。可以使用分块编码逐步渲染内容,但这很简单。

正如您所知,缓冲通常发生在PHP和Web服务器之间的接口中,可以使用进行刷新

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

刷新内容的确切时间对性能有很大影响。如果早期冲洗有好处,那么通常是在头部之后/头部。

为了有效地压缩内容,大多数Web服务器都会对数据进行缓冲。您没有说明您使用的是哪台Web服务器,但如果是Apache 2.x,则可以通过deflateBufferSize指令(比完全禁用缓冲更有效)来减小该缓冲区的大小(以匹配刷新前的块大小)。

如果这是Apache,请确保已启用keepalives。

如果您和服务器之间有更多的代理,那么您对HTTP无能为力,但它们不会影响HTTPS流量。

最后,如果你在客户端上使用防病毒产品,这可能是许多问题的原因——许多问题会中断浏览器和网络之间的网络连接。IME他们在做这件事的质量上经常有很多不足之处。

归根结底,当你不控制基础设施时,你所做的事情是有限的。但除了分块编码/渐进渲染之外,还有其他解决方案。