从CURL中解压缩一个gzip文件,在php上

34

有谁知道如何解压缩通过curl获取的gzip文件内容?

例如:http://torcache.com/torrent/63ABC1435AA5CD48DCD866C6F7D5E80766034391.torrent

回答:

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 09 Jun 2010 01:11:26 GMT
Content-Type: application/x-bittorrent
Content-Length: 52712
Last-Modified: Tue, 08 Jun 2010 15:09:58 GMT
Connection: keep-alive
Expires: Fri, 09 Jul 2010 01:11:26 GMT
Cache-Control: max-age=2592000
Content-Encoding: gzip
Accept-Ranges: bytes

然后压缩使用gzip,我尝试过gzdecode但是不起作用,而gzeflate也无法正常工作,它们都没有返回值,文件内容不超过2k。

7个回答

87

只需告诉 cURL 在响应被 gzip 压缩时自动解压缩

curl_setopt($ch,CURLOPT_ENCODING, '');

3
值应该是空字符串或编码类型,而不是整数。 - redben
1
谢谢!这不是一个明智的默认CURL设置吗? - Tom Carnell
1
@redben 我的建议 在2011年被拒绝了,现在AlixAxel的建议却被批准了。:( - mgutt
如果您想避免编码,请使用“curl_setopt($ch,CURLOPT_ENCODING,'identity')” ,参见链接 - Bryan Sullivan

18

使用gzdecode函数:

<?php
    $c = file_get_contents("http://torcache.com/" .
        "torrent/63ABC1435AA5CD48DCD866C6F7D5E80766034391.torrent");
    echo gzdecode($c);

提供

d8:announce42:http://tracker.openbittorrent.com/announce13:announce-listll42
...

3
是的,确实如此,但我使用的是PHP 5.2版本,他们说gzdecode函数只在6.0版本及以上可用。我在gentoo上配置了PHP和zlib,但似乎无法使用这些gz函数。你有什么想法? :) - PartySoft
6
好的,我有一个解决方案,不太美观,因为我必须将内容写入文件,而不仅仅使用字符串:function gzdecode($data){ $g=tempnam('/tmp','ff'); @file_put_contents($g,$data); ob_start(); readgzfile($g); $d=ob_get_clean(); unlink($g); return $d; }它有效地解决了问题 :) - PartySoft
@PartySoft 那个函数很棒! - barfoon
@PartySoft 谢谢你!非常好用。我正在使用5.3.X版本,但是使用gzuncompress()没有成功。 - donut
我建议使用$length参数,因为它可以保护您的脚本免受内存不足错误的影响。例如,$contents = gzdecode($contents, 10485760);将在结果超过10 MB时停止解压缩。我有几个网站,在gzipped大小小于1 MB之后,经过gzdecode()后它们增长到了30 MB!如果您喜欢CURLOPT_ENCODING,您也可以尝试CURLOPT_WRITEFUNCTION,如果能够通过该函数停止解压缩结果的话。我没有测试过它。 - mgutt
1
别瞎搞,只需要将CURLOPT_ENCODING设置为"gzip",curl就会自动解压缩gzip编码的响应。 - hanshenrik

13

1

你尝试过设置头部,声明你接受gzip编码吗?如下所示:

curl_setopt($rCurl, CURLOPT_HTTPHEADER, array('Accept-Encoding: gzip,deflate'));

4
他已经接收到编码的信息,因此我认为声明他接受编码的信息并不会有任何区别。我尝试向服务器发送"Accept-encoding: none",但服务器没有响应。 - Artefacto

1

使用zlib流包装器:

file_get_contents("compress.zlib://http://torcache.com/" .
    "torrent/63ABC1435AA5CD48DCD866C6F7D5E80766034391.torrent");

0

你可以使用gzinflate来完成它(假设$headers包含所有HTTP头,$buffer包含你的数据):

if (isset($headers['Content-Encoding']) && ($headers['Content-Encoding'] === 'gzip' || $headers['Content-Encoding'] === 'deflate'))
    {
        if ($headers['Content-Encoding'] === 'gzip')
        {
            $buffer = substr($buffer, 10);
        }
        $contents = @gzinflate($buffer);
        if ($contents === false)
        {
            return false;
        }
    }

0

你试过gzuncompress 或者 gzinflate 吗?

gzdeflate压缩,正好相反,不是你想要的。老实说,我搞不清楚gzdecode与正常的解压有什么不同。

还有cURL选项CURLOPT_ENCODING

"Accept-Encoding:" 头的内容。 这可启用响应的解码。 支持的编码有 "identity", "deflate" and "gzip". 如果设置为空字符串,"" ,则会发送包含所有支持的编码类型的头。

看起来它似乎会自动解压响应,但我还没有测试过。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接