谁能解释为什么我收到以下错误?
在代码中,如果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
这可以给人留下什么问题的印象,例如身体内未压缩的部分。
这就是 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();
}