解压缩gzip压缩的http响应


Uncompress gzip compressed http response

我正在使用php的file_get_contents()函数来执行HTTP请求。为了节省带宽,我决定使用stream_context_create()添加"Accept-Encoding: gzip"报头。

显然,file_get_contents()输出的是一个gzip编码的字符串,所以我使用gzuncompress()来解码编码后的字符串,但我收到了一个将数据作为参数传递的错误。

[...] PHP Warning: gzuncompress(): data error in /path/to/phpscript.php on line 26

我知道还有另一个函数可以解压缩gzipped数据gzdecode(),但它没有包含在我的PHP版本中(也许它只在SVN上可用)。

我知道cUrl可以快速解码gzip流(没有任何问题),但有人建议我使用file_get_contents()而不是cUrl。

你知道在PHP中解压缩gzipped数据的其他方法吗?或者gzuncompress()为什么会输出警告?gzuncompress()没有按预期工作是荒谬的。

注意事项:问题当然与PHP有关:HTTP请求是向Tumblr API发出的,它给出了一个编码良好的响应。

发现这对我有用:http://www.php.net/manual/en/function.gzdecode.php#106397

(可选)尝试:http://digitalpbk.com/php/file_get_contents-garbled-gzip-encoding-website-scraping

if ( ! function_exists('gzdecode'))
{
    /**
     * Decode gz coded data
     * 
     * http://php.net/manual/en/function.gzdecode.php
     * 
     * Alternative: http://digitalpbk.com/php/file_get_contents-garbled-gzip-encoding-website-scraping
     * 
     * @param string $data gzencoded data
     * @return string inflated data
     */
    function gzdecode($data) 
    {
        // strip header and footer and inflate
        return gzinflate(substr($data, 10, -8));
    }
}

gzuncompress不适用于gzip编码。它是.Z档案的解压缩功能。

本手册列出了缺少gzdecode()#82930的一些解决方法,或者只使用upgradephp中的解决方法,或gzopen临时文件解决方法。

另一种选择是使用Accept-Encoding:报头强制进行deflate编码,然后使用gzinflate()进行解压缩。

在停用数据之前,您需要对其进行组装。因此,如果标头包含

Transfer-Encoding: chunked

你需要取消锁定。

function http_unchunk($data) {
    $res=[];
    $p=0; $n=strlen($data);
    while($p<$n) {
        if (preg_match("/^([0-9A-Fa-f]+)'r'n/",substr($data,$p,18),$m)) {
            $sz=hexdec($m[1]); $p+=strlen($m[0]);
            $res[]=substr($data,$p,$sz); $p+=$sz+2;
        } else {
            break;
        }
    }
    return implode('',$res);
}

如果内容编码是gzip、x-gzip或x-compression,请使用gzdecode如果内容编码是deflate,请使用gzdeflate

...
if ($chunked) $body=http_unchunk($body);
if ($gzip) $body=gzdecode($body);
if ($deflate) $body=gzdeflate($body);
...