Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php gzcompress()是否随机插入额外数据?_Php_Http_Firefox_Compression_Zlib - Fatal编程技术网

Php gzcompress()是否随机插入额外数据?

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算法,等等等

我整个上午都在研究这个问题,并决定作为最后的努力,也许有人在堆栈溢出问题上为我提供了一个“过去,做了那个”类型的答案

背景最近,我使用过滤器在我们(面向intranet的)Apache(2.2)服务器上实现了压缩,这样所有基于文本的文件(css、js、txt、html等)都可以通过mod_deflate进行压缩,而对php脚本只字不提。在对如何最好地压缩PHP输出进行了大量研究之后,我决定使用gzcompress()风格,因为PHP文档表明使用zlib库和gzip(使用deflate算法,等等等等)比使用ob_gzipwhere()更可取

所以我复制了其他人的方法如下:

<?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;