Php gzcompress()是否随机插入额外数据?
我整个上午都在研究这个问题,并决定作为最后的努力,也许有人在堆栈溢出问题上为我提供了一个“过去,做了那个”类型的答案 背景最近,我使用过滤器在我们(面向intranet的)Apache(2.2)服务器上实现了压缩,这样所有基于文本的文件(css、js、txt、html等)都可以通过mod_deflate进行压缩,而对php脚本只字不提。在对如何最好地压缩PHP输出进行了大量研究之后,我决定使用gzcompress()风格,因为PHP文档表明使用zlib库和gzip(使用deflate算法,等等等等)比使用ob_gzipwhere()更可取 所以我复制了其他人的方法如下:Php gzcompress()是否随机插入额外数据?,php,http,firefox,compression,zlib,Php,Http,Firefox,Compression,Zlib,我整个上午都在研究这个问题,并决定作为最后的努力,也许有人在堆栈溢出问题上为我提供了一个“过去,做了那个”类型的答案 背景最近,我使用过滤器在我们(面向intranet的)Apache(2.2)服务器上实现了压缩,这样所有基于文本的文件(css、js、txt、html等)都可以通过mod_deflate进行压缩,而对php脚本只字不提。在对如何最好地压缩PHP输出进行了大量研究之后,我决定使用gzcompress()风格,因为PHP文档表明使用zlib库和gzip(使用deflate算法,等等等
<?php # start each page by enabling output buffering and disabling automatic flushes
ob_start();ob_implicit_flush(0);
(program logic)
print_gzipped_page();
function print_gzipped_page() {
if (headers_sent())
$encoding = false;
elseif(strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'x-gzip') !== false )
$encoding = 'x-gzip';
elseif(strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip') !== false )
$encoding = 'gzip';
else
$encoding = false;
if($encoding){
$contents = ob_get_contents(); # get contents of buffer
ob_end_clean(); # turn off OB and flush buffer
$size = strlen($contents);
if ($size < 512) { # too small to be worth a compression
echo $contents;
exit();
} else {
header("Content-Encoding: $encoding");
header('Vary: Accept-Encoding');
# 8-byte file header: g-zip file (1f 8b) compression type deflate (08), next 5 bytes are padding
echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
$contents = gzcompress($contents, 9);
$contents = substr($contents, 0,$size); # faster than not using a substr, oddly
echo $contents;
exit();
}
} else {
ob_end_flush();
exit();
}
}
好的,首先,您似乎没有设置内容长度标题,这会导致问题,相反,您正在使gzip内容变长,以便它与您在第一位收到的内容长度大小相匹配。这会变得难看的。我的建议是你更换这些线路
# 8-byte file header: g-zip file (1f 8b) compression type deflate (08), next 5 bytes are padding
echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
$contents = gzcompress($contents, 9);
$contents = substr($contents, 0,$size); # faster than not using a substr, oddly
echo $contents;
与
看看这是否有助于解决这个问题。丁!叮!叮!在整个周末都在思考这个问题之后,在第无数次重读PHP手册页之后,我终于找到了答案。。。从zlib PHP文档中,“是否透明地压缩页面。”透明地!与中一样,一旦zlib.output\u compression设置为“On”,就不需要其他任何东西来让PHP压缩其输出。是啊,很尴尬
出于未知原因,从PHP脚本显式调用的代码正在压缩已经压缩的内容,而浏览器只是展开一层压缩并显示结果。奇怪的是,当output_compression打开或关闭时,内容的strlen()没有变化,因此透明压缩必须在显式压缩之后发生,但它偶尔决定不压缩已经压缩的内容
不管怎样,只要把PHP留给自己的设备就可以解决所有问题。zlib不需要输出缓冲或任何东西来压缩输出
希望这能帮助其他人在HTTP压缩的奇妙世界中挣扎。很自然,当我发布这一消息时,我机器上的Firefox最终从服务器上检索到了损坏的数据。èxÚµ™moÛ6ßßßßSWell,我已经尝试显式声明内容长度,但它没有改变任何东西。在压缩内容之前回显gzip头应该可以,因为调用了ob_end_clean(),它会擦除缓冲区的内容并停止输出缓冲,所以头不会与其余内容一起编码。我已经启用了显式声明内容长度,但这并没有解决之前的问题,所以我的希望不是很高。你说的“相反,你正在使gzip内容变长,以便它与你在第一位收到的内容长度大小相匹配”是什么意思?是的,这仍然不能防止出现错误(如果这是一个错误的话)发生了。不过,Firefox似乎需要再刷新几次才能步履蹒跚。
$compressed = gzcompress($contents, 9);
$compressed_length = strlen($compressed); /* contains no nulls i believe */
header("Content-length: $compressed_length");
echo "\x1f\x8b\x08\x00\x00\x00\x00\x00", $compressed;