You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PHP cURL无法获取Content Encoding的技术求助

问题

使用PHP的cURL库获取目标资源的Content Type和Content Encoding时,Content Type能正常获取,但Content Encoding始终为空。测试URL https://affiliatefix.com/sitemap-1.xml 实际返回gzip编码,但无法通过代码捕获到。

原代码:

function get_content_type_curl($url_content_type) {
    
    $agent_content_type = $_SERVER['HTTP_USER_AGENT'];
    $ch_content_type = curl_init();

    curl_setopt($ch_content_type, CURLOPT_URL, $url_content_type);
    curl_setopt($ch_content_type, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch_content_type, CURLOPT_HEADER, 0);
    curl_setopt($ch_content_type, CURLOPT_NOBODY, 1);
    curl_setopt($ch_content_type, CURLOPT_USERAGENT, $agent_content_type);
    curl_setopt($ch_content_type, CURLOPT_FOLLOWLOCATION, 1);

    curl_exec($ch_content_type);
    $content_type = curl_getinfo($ch_content_type, CURLINFO_CONTENT_TYPE);
    $content_encoding = defined('CURLINFO_CONTENT_ENCODING') ? curl_getinfo($ch_content_type, CURLINFO_CONTENT_ENCODING) : '';
    //$content_encoding = curl_getinfo($ch_content_type, CURLINFO_CONTENT_ENCODING);

    curl_close($ch_content_type);

    return array("content_type" => $content_type, "content_encoding" => $content_encoding);
}

$result = get_content_type_curl("https://affiliatefix.com/sitemap-1.xml");

echo $result["content_type"] . "\n";
if (!empty($result["content_encoding"])) {
    echo $result["content_encoding"] . "\n";
}

/**if (strpos($result["content_encoding"], "gzip") !== false) {
    echo $result["content_encoding"] . "\n";
} else {
    echo "No encoding".$result["content_encoding"] . "\n";
}**/
原因分析
  1. HEAD请求局限性:代码设置CURLOPT_NOBODY = 1会发送HEAD请求,部分服务器对HEAD请求的响应不会返回Content-Encoding头,因为HEAD仅用于获取元数据,服务器可能省略编码相关信息。
  2. 未声明编码支持:没有向服务器发送Accept-Encoding请求头,服务器默认不会返回编码信息,即使资源本身是压缩状态。
  3. 版本兼容性:CURLINFO_CONTENT_ENCODING常量需要cURL 7.21.0+和PHP 5.3.10+支持,环境版本过低会导致该常量未定义,返回空值。
解决方案

方案1:改用GET请求解析响应头

去掉CURLOPT_NOBODY,设置CURLOPT_HEADER = 1发送GET请求,从响应头中提取编码信息:

function get_content_info($url) {
    $agent = $_SERVER['HTTP_USER_AGENT'];
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 1); // 包含响应头
    curl_setopt($ch, CURLOPT_NOBODY, 0); // 发送GET请求
    curl_setopt($ch, CURLOPT_USERAGENT, $agent);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Accept-Encoding: gzip, deflate' // 声明支持的编码
    ]);

    $response = curl_exec($ch);
    $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
    $headers = substr($response, 0, $header_size);
    
    $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
    
    // 解析Content-Encoding
    $content_encoding = '';
    if (preg_match('/Content-Encoding:\s*(.*?)\s*$/mi', $headers, $matches)) {
        $content_encoding = trim($matches[1]);
    }

    curl_close($ch);

    return [
        "content_type" => $content_type,
        "content_encoding" => $content_encoding
    ];
}

$result = get_content_info("https://affiliatefix.com/sitemap-1.xml");

echo $result["content_type"] . "\n";
if (!empty($result["content_encoding"])) {
    echo $result["content_encoding"] . "\n";
}

方案2:保留HEAD请求,添加编码支持头

继续使用HEAD请求,补充Accept-Encoding头告知服务器支持的编码类型:

function get_content_type_curl($url_content_type) {
    $agent_content_type = $_SERVER['HTTP_USER_AGENT'];
    $ch_content_type = curl_init();

    curl_setopt($ch_content_type, CURLOPT_URL, $url_content_type);
    curl_setopt($ch_content_type, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch_content_type, CURLOPT_HEADER, 0);
    curl_setopt($ch_content_type, CURLOPT_NOBODY, 1);
    curl_setopt($ch_content_type, CURLOPT_USERAGENT, $agent_content_type);
    curl_setopt($ch_content_type, CURLOPT_FOLLOWLOCATION, 1);
    // 添加Accept-Encoding头
    curl_setopt($ch_content_type, CURLOPT_HTTPHEADER, [
        'Accept-Encoding: gzip, deflate'
    ]);

    curl_exec($ch_content_type);
    $content_type = curl_getinfo($ch_content_type, CURLINFO_CONTENT_TYPE);
    $content_encoding = defined('CURLINFO_CONTENT_ENCODING') ? curl_getinfo($ch_content_type, CURLINFO_CONTENT_ENCODING) : '';

    curl_close($ch_content_type);

    return array("content_type" => $content_type, "content_encoding" => $content_encoding);
}

$result = get_content_type_curl("https://affiliatefix.com/sitemap-1.xml");

echo $result["content_type"] . "\n";
if (!empty($result["content_encoding"])) {
    echo $result["content_encoding"] . "\n";
}

额外注意事项

  • 检查PHP和cURL版本,确保CURLINFO_CONTENT_ENCODING常量可用;
  • 部分服务器对不同User-Agent返回不同响应头,确保使用的User-Agent符合服务器预期;
  • 方案1中若资源较大,可设置CURLOPT_RANGE = '0-0'仅请求部分内容,减少带宽消耗。

内容的提问来源于stack exchange,提问作者Mehul Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 04:03:19