您的应用程序的输出应该只包含一种输出编码。如果您有多个编码不同的块,那么浏览器将获得无法使用的结果。因此编码错误。
Kohana 本身已经使用了输出缓冲区。如果你想将它与你的 ob_gzhandler 输出缓冲区结合起来,你需要在 kohana 初始化它自己之前启动你的缓冲区。那是因为输出缓冲区是可堆叠的。当 kohana 完成它的输出缓冲后,你的将应用:
ob_start('ob_gzhandler'); # your buffer:
ob_starts and ends by kohana
因此,只要 kohana 完成了一些输出,这些块就会被传递到您的输出回调 (ob_gzhandler()) 中,并将被 gz 编码。
浏览器应该只获取 gz 编码的数据,因为它是最顶层的输出缓冲区。
使用 ob_gzhandler 并手动回显缓冲区
如果您使用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 通过回调推送缓冲区。
使用 Curl 检查 HTTP 压缩问题
由于 Firefox 会返回错误,因此需要另一个工具来检查导致编码错误的原因。您可以使用curl 来跟踪正在发生的事情:
curl --compress -i URL
将请求启用压缩的 URL,同时显示所有响应标头和未编码的正文。这是必要的,因为 PHP 会根据请求标头透明地启用/禁用 ob_gzhandler 回调的压缩。
响应还表明 PHP 也会设置所需的响应标头。因此无需手动指定它们。那将更加危险,因为仅通过调用ob_start('ob_gzhandler') 您无法确定是否启用了压缩。
如果压缩被破坏,curl 将给出错误描述但不会显示正文。
以下是这样的 curl 错误消息,由错误的 php 脚本生成的输出不完整:
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
这可以让人知道出了什么问题,比如身体内未压缩的部分。