如果代码中的
echo $gz;
被注释掉,我就不会收到任何错误(但也没有输出!),如果没有注释,我就会从Firefox中得到以下错误:
内容编码错误
由于使用了无效或不支持的压缩形式,无法显示您要查看的页面。
感谢您的帮助,以下是代码:
ob_start('ob_gzhandler') OR ob_start();
echo 'eh?';
$gz = ob_get_clean();
echo $gz;
echo $gz;
被注释掉,我就不会收到任何错误(但也没有输出!),如果没有注释,我就会从Firefox中得到以下错误:
内容编码错误
由于使用了无效或不支持的压缩形式,无法显示您要查看的页面。
ob_start('ob_gzhandler') OR ob_start();
echo 'eh?';
$gz = ob_get_clean();
echo $gz;
你的应用程序输出应只包含一种输出编码。如果有多个块使用不同的编码,则浏览器将无法处理结果。因此产生编码错误。
Kohana本身已经使用了输出缓冲区。如果你想要将其与ob_gzhandler输出缓冲区结合使用,你需要在kohana初始化自己之前启动你的缓冲区。这是因为输出缓冲区是可以堆叠的。当kohana完成其输出缓冲时,你的缓冲区将被应用:
ob_start('ob_gzhandler'); # your buffer:
ob_starts and ends by kohana
每当kohana进行一些输出时,这些块将传递到您的输出回调函数(ob_gzhandler()
)中并进行gz编码。
然后,浏览器应该只获取到经过gz编码的数据,因为它是顶级输出缓冲区。
如果您使用ob_start('ob_gzhandler')
让PHP处理压缩,然后echo ob_get_clean()
,则会创建不可靠的输出。这与压缩与输出缓冲区一起工作的方式有关:
PHP将缓存输出块。这意味着PHP开始压缩输出但保留一些字节以继续压缩。因此,ob_get_clean()返回到目前为止已压缩的缓冲区部分。通常,该结果不完整。
为了解决这个问题,请先刷新缓冲区:
ob_start('ob_gzhandler') OR ob_start();
echo 'eh?';
ob_flush();
$gz = ob_get_clean();
echo $gz;
同时确保你之后没有更多的输出。
如果你的PHP脚本已经到达了结尾,它会自动处理这个问题:刷新并输出缓冲区。
现在,你需要手动调用ob_flush()
来显式地让PHP通过回调函数推送缓冲区。
由于Firefox会返回错误信息,所以需要另一个工具来检查编码错误的原因。你可以使用curl
跟踪发生了什么:
curl --compress -i URL
将启用压缩并显示所有响应头和未编码的正文来请求URL。这是必要的,因为PHP会根据请求头透明地启用/禁用ob_gzhandler
回调的压缩。
响应还显示PHP将设置所需的响应头,因此无需手动指定它们。这甚至是危险的,因为仅通过调用ob_start('ob_gzhandler')
无法确定是否启用了压缩。
如果压缩损坏,curl
会给出错误描述但不会显示正文。
以下是使用有缺陷的PHP脚本生成的不完整输出引发的curl错误消息:
HTTP/1.1 200 OK
X-Powered-By: PHP/5.3.6
Content-Encoding: gzip
...
curl: (23) Error while processing content unencoding: invalid code lengths set
通过添加--raw
开关,您甚至可以查看原始响应正文:
curl --compress --raw -i URL
这可以给人一种什么出了问题的印象,比如身体内未经压缩的部分。
curl
,似乎响应是未经编码的,但带有Content-Encoding: gzip
,因此在解码时出现错误。 - tjmob_get_clean
实际上不会包含任何内容,因为 ob_flush
会丢弃缓冲区的内容。 - tjm这就是 phpharo 的作用:
/** output buffring */
if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false)
{
ob_start('ob_gzhandler'); ob_start();
}
else
{
ob_start();
}
Content-Encoding
头,但是 Firebug 显示它已经正确设置了,我现在也尝试手动设置了,但是没有任何区别。我知道在我的示例中"eh?"
没有被压缩 - 正如我在问题中提到的那样,我只是用它来显示无论我返回压缩内容与否都会出现错误。我想我会让它更清楚一些。谢谢。 - tjm