2012-10-09 88 views
1

当我运行curl -I http://api.stackoverflow.com/1.1/badges来回我的终端,它让我看到下面的标题:PHP卷曲不返回Content-Encoding头

HTTP/1.1 200 OK 
Cache-Control: private 
Content-Length: 42804 
Content-Type: application/json; charset=utf-8 
Content-Encoding: gzip 
X-AspNetMvc-Version: 4.0 
X-RateLimit-Max: 300 
X-RateLimit-Current: 297 
X-AspNet-Version: 4.0.30319 
Set-Cookie: .ASPXBrowserOverride=; expires=Mon, 08-Oct-2012 04:29:28 GMT; path=/ 
Date: Tue, 09 Oct 2012 04:29:27 GMT 

然而,当我运行通过PHP一样卷曲的要求,我得到这个:

Array 
(
    [url] => http://api.stackoverflow.com/1.1/badges?10102 
    [content_type] => application/json; charset=utf-8 
    [http_code] => 200 
    [header_size] => 277 
    [request_size] => 85 
    [filetime] => -1 
    [ssl_verify_result] => 0 
    [redirect_count] => 0 
    [total_time] => 0.168343 
    [namelookup_time] => 0.023417 
    [connect_time] => 0.046293 
    [pretransfer_time] => 0.046365 
    [size_upload] => 0 
    [size_download] => 42804 
    [speed_download] => 254266 
    [speed_upload] => 0 
    [download_content_length] => 42804 
    [upload_content_length] => 0 
    [starttransfer_time] => 0.097563 
    [redirect_time] => 0 
    [certinfo] => Array 
     (
     ) 

    [redirect_url] => 
) 

与我有关的主要区别是,当通过PHP运行,我没有得到Content-Encoding头,没有它,如果内容需要在gzip的膨胀或不我不知道。

有没有办法获得Content-Encoding标题,或者通过其他方式检查gzip压缩?

回答

4

有一个在没有返回header_response也不accept-encodinggetinfo数组。我认为getinfo上的CURLINFO_HEADER_OUT会给出响应标题,但只给出请求标题。

但是,您可以使用CURLOPT_HEADER选项设置为true来获取原始标题。所以我建议你做点不太自然的事情:

$curl = curl_init(); 

$opts = array (
     CURLOPT_URL => 'http://api.stackoverflow.com/1.1/badges', 
     CURLOPT_TIMEOUT => 120, 
     CURLOPT_RETURNTRANSFER => true, 
     CURLOPT_FOLLOWLOCATION => true, 
     CURLOPT_ENCODING => 'gzip', 
     CURLOPT_HEADER => true, 
); 
curl_setopt_array($curl, $opts); 

$return = curl_exec($curl); 

list($rawHeader, $response) = explode("\r\n\r\n", $return, 2); 

$cutHeaders = explode("\r\n", $rawHeader); 
$headers = array(); 
foreach ($cutHeaders as $row) 
{ 
    $cutRow = explode(":", $row, 2); 
    $headers[$cutRow[0]] = trim($cutRow[1]); 
} 

echo $headers['Content-Encoding']; // gzip 
3

如果将CURLOPT_HEADER设置为true,curl会将标题返回到正文的旁边。如果您只是对标题感兴趣,则可以将CURLOPT_NOBODY设置为true,并且不返回正文(模拟命令行中的-I标志)。

此示例设置只是CURLOPT_HEADER,读取Content-Encoding头(如果设置),并解压缩体:​​

$curl = curl_init(); 

curl_setopt($curl, CURLOPT_URL, "http://api.stackoverflow.com/1.1/badges"); 
curl_setopt($curl, CURLOPT_HEADER, 1); 
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 

$response = curl_exec($curl); 
curl_close($curl); 

list($header, $body) = explode("\r\n\r\n", $response, 2); 
if(preg_match('@Content-Encoding:\s+(\w+)@i', $header, $match)) { 
    switch (strtolower($match[1])) { 
     case 'gzip': 
      $body = gzdecode($body); 
     break; 

     case 'compress': 
      $body = gzuncompress($body); 
     break; 

     case 'deflate': 
      $body = gzdeflate($body); 
     break; 
    } 
} 
echo $header; 
echo $body; 

免责声明:gzdecode可能不是在你的PHP版本。我已经用PHP 5.4.4测试过它,它工作。

您还可以安装HTTP_Request2 -PEAR包,它会替你(再加上你可以方便地前往头,不HTTP头解析):

include 'HTTP/Request2.php'; 
$request = new HTTP_Request2('http://api.stackoverflow.com/1.1/badges', 
    HTTP_Request2::METHOD_GET); 

$response = $request->send(); 

echo $response->getBody();