對接第三方 HTTP 接口,json_decode($response) 永遠返回 null,但將響應字符串複製到代碼中直接賦值卻能正常解析。經排查,接口響應頭部攜帶 UTF-8 BOM (Byte Order Mark),導致 JSON 解析器識別失敗。
json_decode($jsonStr, true) 返回 null,json_last_error() 為 JSON_ERROR_SYNTAX。var_dump($jsonStr) 顯示長度比肉眼可見字符多 3 字節。JSON.parse() 正常(瀏覽器自動忽略 BOM)。UTF-8 BOM 為十六進制 EF BB BF 三字節,位於文件/流開頭。PHP json_decode 不會自動剝離,導致語法錯誤。
解析前檢測並移除 BOM:
if (substr($response, 0, 3) === pack('CCC', 0xEF, 0xBB, 0xBF)) {
$response = substr($response, 3);
}
$data = json_decode($response, true);
pack('CCC', ...) 構建二進制 BOM 字符串,避免編碼問題;substr 直接切片,性能極高。
封裝為工具函數,統一處理所有外部 JSON 輸入:
function safeJsonDecode($json, $assoc = true) {
// 移除 UTF-8 BOM
if (strlen($json) >= 3 && substr($json, 0, 3) === "\xEF\xBB\xBF") {
$json = substr($json, 3);
}
return json_decode($json, $assoc);
}
str_replace("\xE2\x80\x8B", '', $json)FF FE / FE FF,需配合 mb_convert_encoding 處理。preg_replace('/[\x00-\x1F\x7F]/', '', $json) 清理不可見控制字符。對接外部接口時,永不信任輸入純淨度,統一接入層做清洗,可避免 90% 的詭異解析失敗。