9

谁能解释为什么我收到以下错误?

在代码中,如果echo $gz;注释掉我没有收到错误(但也没有输出!),如果不是我得到(来自 Firefox),

内容编码错误


您尝试查看的页面无法显示,因为它使用了无效或不受支持的压缩形式。


感谢您的帮助,代码如下:

ob_start('ob_gzhandler') OR ob_start();
echo 'eh?';
$gz = ob_get_clean();
echo $gz;
4

2 回答 2

16

您的应用程序的输出应该只包含一种输出编码。如果您有多个编码不同的块,那么浏览器将获得无法使用的结果。因此编码错误。

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将给出错误描述但不会显​​示正文。

以下是由错误的 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

这可以给人留下什么问题的印象,例如身体内未压缩的部分。

于 2011-06-19T15:21:31.230 回答
0

这就是 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();
}
于 2013-11-04T10:57:27.620 回答