cURL 万能调试模板(含编码自动判断 + Header 输出)

58 阅读2分钟

适用场景:
✔ PHP 调第三方 API 返回乱码
✔ 接口偶尔失败、不稳定
✔ 想搞清楚是接口问题,还是自己代码问题


一、先上「万能调试函数」(直接复制就能用)

function curlDebug($url, $method = 'GET', $data = [], $headers = [])
{
    $ch = curl_init();

    // 请求方式
    if (strtoupper($method) === 'POST') {
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    } else {
        if (!empty($data)) {
            $url .= (strpos($url, '?') === false ? '?' : '&')
                . http_build_query($data);
        }
    }

    curl_setopt_array($ch, [
        CURLOPT_URL            => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HEADER         => true,   // 关键:返回 header + body
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_TIMEOUT        => 15,
        CURLOPT_ENCODING       => '',     // 自动解 gzip / deflate
        CURLOPT_HTTPHEADER     => $headers,
    ]);

    $response = curl_exec($ch);

    if ($response === false) {
        return [
            'error' => curl_error($ch),
        ];
    }

    // 分离 header 和 body
    $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
    $rawHeader  = substr($response, 0, $headerSize);
    $body       = substr($response, $headerSize);

    curl_close($ch);

    // ===== 编码判断 =====
    $encoding = mb_detect_encoding(
        $body,
        ['UTF-8', 'GBK', 'GB2312', 'BIG5', 'ISO-8859-1'],
        true
    );

    // 如果不是 UTF-8,转成 UTF-8
    if ($encoding && $encoding !== 'UTF-8') {
        $body = mb_convert_encoding($body, 'UTF-8', $encoding);
    }

    return [
        'http_header' => $rawHeader,
        'detected_encoding' => $encoding ?: '未知',
        'body' => $body,
    ];
}

二、怎么用?(新手 3 秒上手)

$result = curlDebug('https://api.example.com/test');

echo "<pre>";
print_r($result);

你能一次性看到:

  • ✅ 接口完整 Header
  • ✅ 实际返回内容
  • ✅ 系统判断的编码类型
  • ✅ 是否被自动转成 UTF-8

📌 调试阶段千万别直接 echo 接口内容,一定要先 print_r。


三、这个模板到底“万能”在哪?

我给你拆一下它解决的 真实痛点


① 自动判断编码(不再瞎猜)

mb_detect_encoding(...)

能直接告诉你:

  • UTF-8
  • GBK
  • GB2312
  • 还是其他奇葩编码

你不用再靠肉眼猜乱码。


② 自动解 gzip(很多人卡死在这)

CURLOPT_ENCODING => ''

这一行,解决了:

  • 看着像乱码
  • 实际是 gzip 压缩二进制

👉 不加这一句,很多接口你永远看不懂返回值。


③ Header 和 Body 强制分离(查问题神器)

CURLOPT_HEADER => true

你可以清楚看到:

  • Content-Type
  • charset
  • 是否 gzip
  • 服务端到底声明了什么

📌 很多接口:Header 写 UTF-8,Body 实际是 GBK,一眼就能发现。


四、最常见的 3 种调试结果解读

情况 1:编码显示 UTF-8,但内容还是乱码

👉 接口声明不可信,实际编码是假的

解决:
手动指定正确编码再转。


情况 2:编码是 GBK,转完就正常

👉 最理想情况,问题结束


情况 3:编码检测失败,全是怪字符

👉 多半是:

  • gzip 没解
  • 或接口本身返回的不是文本

五、强烈建议的调试顺序(少走 80% 弯路)

1️⃣ 用这个模板看 原始返回
2️⃣ 确认 Header 的 charset
3️⃣ 看 detect_encoding 的结果
4️⃣ 再决定要不要转码

千万别一上来就 iconv / mb_convert_encoding 乱试。

接口乱码不是玄学,
你只是缺一个:

能把“原始真相”扒出来的 cURL 模板。