我刚把我的网站移到GoDaddy托管,一切都正常了,但PHP脚本不会立即输出数据——它们会缓冲,直到脚本运行完毕,然后一次呈现整个页面。显然,对于长脚本来说,这是个问题。我的老主人以前不这么做,GoDaddy的支持者说他们对此无能为力。以下是我已经尝试过的(没有成功)
- 禁用输出压缩(zlib、gzip)
- 在php.ini中设置
output_buffering = off
- 设置
Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
、Pragma "no-cache"
、Expires "Wed, 10 May 1985 09:00:00 GMT"
的标头,并取消设置ETag
标头 - 我还尝试在脚本本身中设置缓冲值,使用
ini_set('output_buffering', 'off')
、ini_set('zlib.output_compression', false)
、while (@ob_end_flush())
、ini_set('implicit_flush', true)
和ob_implicit_flush(true)
- 我尝试在每次
echo
输出后运行flush()
和ob_flush()
命令 - 尝试将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他们在做这件事的质量上经常有很多不足之处。
归根结底,当你不控制基础设施时,你所做的事情是有限的。但除了分块编码/渐进渲染之外,还有其他解决方案。