curl获取含中文JSON字符串解码异常及json_decode返回null问题排查
问题1:curl获取的JSON含中文时显示/解码异常
这种情况大概率是编码不匹配搞的鬼,我之前对接第三方接口时踩过好几次这个坑,给你几个排查方向:
让curl自动处理响应编码:默认情况下curl可能不会自动解析响应的编码,你可以在初始化curl后加上这行代码:
curl_setopt($ch, CURLOPT_ENCODING, "");它会让curl自动识别并处理服务器返回的gzip、deflate等编码,同时也能避免编码转换时的乱码问题。
强制统一编码为UTF-8:如果接口返回的是GBK/GB2312编码的JSON,直接用json_decode肯定会乱码,你可以先把返回内容转成UTF-8:
$response = curl_exec($ch); $response = mb_convert_encoding($response, 'UTF-8', 'GBK'); // 根据实际编码调整第二个参数检查响应头的编码声明:用
curl_getinfo($ch, CURLINFO_CONTENT_TYPE)获取返回的Content-Type头,确认是否带有charset=utf-8,如果接口没声明编码,很可能会导致本地解析时用错编码。
问题2:json_decode解析返回内容时返回null
这个问题的排查关键是找到具体错误原因,别瞎猜,直接用json_last_error_msg()看报错信息!常见原因有这些:
JSON字符串语法错误:JSON对格式要求非常严格,比如末尾不能有多余逗号、字符串必须用双引号、不能有未转义的特殊字符(比如换行符)。举个反例:
{"name":"张三", "age":25,} // 末尾的逗号是非法的这种情况json_decode直接返回null,用
json_last_error_msg()会提示Syntax error。字符串含不可见字符(比如UTF-8 BOM):有些接口返回的JSON开头会带BOM头(三个不可见字符),这会导致json_decode识别失败。你可以用trim去掉:
$response = trim($response, "\xEF\xBB\xBF"); // 去掉UTF-8 BOM编码问题延续:如果第一个问题的中文乱码没解决,JSON字符串本身是无效的UTF-8,json_decode也会返回null,这时候
json_last_error_msg()会提示Malformed UTF-8 characters, possibly incorrectly encoded,先解决编码问题再试。内存不足(少见但存在):如果JSON数据特别大,超过了PHP的
memory_limit设置,json_decode也会返回null。你可以临时调整内存限制:ini_set('memory_limit', '256M');
内容的提问来源于stack exchange,提问作者mamachichi

