PHP输出缓冲,由ob_gzhandler引起的内容编码错误? [英] PHP Output buffering, Content Encoding Error caused by ob_gzhandler?
问题描述
任何人都可以解释为什么我收到以下错误吗?
Can anyone explain why I am receiving the following error?
在代码中,如果echo $gz;
被注释掉,我不会收到任何错误(但也不会输出!),如果不是,我会收到(从Firefox),
In the code, if the echo $gz;
is commented out I receive no error (but also no output!), if it isn't I get (from Firefox),
内容编码错误
您的页面 试图查看无法显示 因为它使用了无效或 不支持的压缩形式.
The page you are trying to view cannot be shown because it uses an invalid or unsupported form of compression.
感谢您的帮助,下面是代码:
Thanks for your help, here's the code:
ob_start('ob_gzhandler') OR ob_start();
echo 'eh?';
$gz = ob_get_clean();
echo $gz;
推荐答案
应用程序的输出应仅包含一种输出编码.如果您有多个块的编码方式不同,那么浏览器将得到无法使用的结果.因此出现编码错误.
The output of your application should only contain one output encoding. If you have multiple chunks that are encoded differently, then the browser will get a result that it is impossible to work with. Hence the encoding error.
Kohana本身已经使用了输出缓冲区.如果要将其与ob_gzhandler输出缓冲区结合使用,则需要在kohana初始化自己的缓冲区之前启动缓冲区.那是因为输出缓冲区是可堆叠的.当kohana完成输出缓冲后,您的将应用:
Kohana itself makes already use of the output buffer. If you want to combine that with your ob_gzhandler output buffer, you need to start your buffer before kohana initialized it's own. That's because output buffer are stackable. When kohana has finished it's output buffering, yours will apply:
ob_start('ob_gzhandler'); # your buffer:
ob_starts and ends by kohana
因此,每当kohana完成某些输出时,这些块都将传递到您的输出回调中( ob_gzhandler()
),并将进行gz编码.
So whenever kohana has done some output, these chunks will get passed on into your output callback (ob_gzhandler()
) and will be gz-encoded.
然后,浏览器应该只获取gz编码的数据,因为它是最顶层的输出缓冲区.
The browser should then only get gz-encoded data as it was the output buffer at the topmost level.
如果使用ob_start('ob_gzhandler')
来让PHP处理压缩,然后又使用echo ob_get_clean()
,则将创建不可靠的输出.这与压缩与输出缓冲的工作方式有关:
If you make use of ob_start('ob_gzhandler')
to let PHP deal with the compression and you then echo ob_get_clean()
, you will create an unreliable output. That's related to how the compression togther with output buffering works:
PHP将缓冲输出的块.这意味着,PHP开始压缩输出,但保留一些字节以继续压缩.因此,ob_get_clean()返回缓冲区的当前压缩部分.通常结果是不完整的.
PHP will buffer chunks of output. That means, PHP starts to compress the output but keeps some bytes to continue compressing. So ob_get_clean() returns the so-far compressed part of the buffer. Often that result is not complete.
要解决此问题,请先刷新缓冲区:
To deal with that, flush the buffer first:
ob_start('ob_gzhandler') OR ob_start();
echo 'eh?';
ob_flush();
$gz = ob_get_clean();
echo $gz;
并确保之后没有其他输出.
And ensure you don't have any more output after that.
如果您要让PHP到达脚本的末尾,则可以解决此问题:刷新并输出.
If you would have PHP reached the end of your script, it would have taken care of that: Flushing and outputting.
现在,您需要手动调用ob_flush()
,以使PHP通过回调显式推送缓冲区.
Now you need to manually call ob_flush()
to explicitly make PHP push the buffer through the callbacks.
由于firefox将返回错误,因此需要另一个工具来检查导致编码错误的原因.您可以使用 curl
来跟踪正在发生的事情:
As firefox will return an error, another tool to inspect what's causing the encoding error is needed. You can use curl
to track what's going on:
curl --compress -i URL
在显示所有响应标头和未编码的正文时,将请求启用了压缩的URL.这是必要的,因为PHP会根据请求标头透明地启用/禁用ob_gzhandler
回调的压缩.
Will request the URL with compression enabled while displaying all response headers and the body unencoded. This is necessary as PHP transparently enables / disables compression of the ob_gzhandler
callback based on request headers.
响应还显示PHP也将设置所需的响应头.因此,无需手动指定它们.这甚至是危险的,因为仅通过调用ob_start('ob_gzhandler')
您就无法确定是否启用了压缩.
A response also shows that PHP will set the needed response headers as well. So no need to specify them manually. That would be even dangerously, because only by calling ob_start('ob_gzhandler')
you can not say if compression is enabled or not.
如果压缩失败,则curl
将给出错误描述,但不会显示主体.
In case the compression is broken, curl
will give an error description but would not display the body.
以下是这样的卷曲错误消息,它是由错误的php脚本生成的输出不完整而引起的:
Following is such a curl error message provoked with an incompletely generated output by a faulty php script:
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
开关,您甚至可以在原始响应主体中达到顶峰:
By adding the --raw
switch, you can even peak into the raw response body:
curl --compress --raw -i URL
这可能会给人留下深刻的印象,例如身体中未压缩的部分.
That can give an impression what's going wrong, like uncompressed parts within the body.
这篇关于PHP输出缓冲,由ob_gzhandler引起的内容编码错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!