json_validate() 不处理 utf-8 bom(\xef\xbb\xbf),因其违反 rfc 7159 关于 json 必须以有效字符开头的规定,导致语法扫描失败并返回 false;正确做法是调用前用 ltrim($json, "\xef\xbb\xbf") 预清除 bom。

json_validate() 本身不处理 BOM 头,遇到 UTF-8 BOM(\xEF\xBB\xBF)会直接判定为非法 JSON。这不是校验“不准确”,而是符合规范的行为——BOM 不属于合法 JSON 字符,RFC 7159 明确要求 JSON 文本必须以有效字符开头,而 BOM 是非打印字节序列。
为什么带 BOM 的字符串通不过 json_validate()
BOM 位于字符串最前端,破坏了 JSON 的起始结构。例如:"\xEF\xBB\xBF{\"name\":\"张三\"}" 实际开头是三个二进制字节,不是 {,因此语法扫描失败,json_validate() 返回 false,json_last_error() 通常返回 JSON_ERROR_SYNTAX 或 JSON_ERROR_UTF8(取决于解析器内部处理路径)。
正确做法:验证前先清除 BOM
不要依赖 json_validate() 自动识别或跳过 BOM。应在调用前做预处理:
- 用
ltrim($json, "\xEF\xBB\xBF")去掉开头的 BOM 字节(安全、轻量、推荐) - 若还需兼容其他编码标记(如 UTF-16),可扩展为正则匹配:
preg_replace('/^\x{FEFF}/u', '', $json) - 注意:BOM 清理必须在
json_validate()之前,且仅需一次;重复清理无害但没必要
别和 json_decode() 连用,也别清洗后还传错编码
常见错误组合:
- 先
ltrim(),再json_validate(),紧接着又json_decode()→ 白费一次解析(json_decode()内部也会校验) - 清洗后没确保字符串仍是 UTF-8(比如从 GBK 源转来),
json_validate()可能因编码问题失败 - 把
$_POST['data']或file_get_contents('php://input')原样传入,没清洗也没检查编码
建议流程:获取原始字符串 → ltrim(..., "\xEF\xBB\xBF") → mb_check_encoding($json, 'UTF-8') ? $json : false(可选强校验)→ json_validate()。
补充:服务端文件本身的 BOM 也要清
如果 JSON 数据来自 PHP 文件内嵌(如 file_get_contents('config.json')),而该 JSON 文件本身带 BOM,同样会导致读取内容开头含 BOM。此时应从源头清理 JSON 文件,而非每次读取都 trim。可用 Notepad++ “转为 UTF-8 无 BOM 格式”保存,或 Linux 下用 sed -i '1s/^\xEF\xBB\xBF//' config.json 批量修复。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











