判断原始JSON类型应检查trim($json)[0]:为'{'是对象,'['是数组;验证合法性需json_decode()后用json_last_error()===JSON_ERROR_NONE,且先排除空或纯空白字符串。

json_decode() 返回值类型不等于 JSON 原始结构类型
很多人以为 json_decode('{"a":1}') 返回对象就代表原始是对象,json_decode('[1,2]') 返回数组就代表原始是数组——这会导致误判。因为 json_decode() 的返回类型由第二个参数 $assoc 决定,和输入 JSON 无关:json_decode('{"a":1}', true) 返回数组,json_decode('{"a":1}', false) 返回 stdClass。你不能靠 is_array() 或 is_object() 反推原始 JSON 是对象还是数组。
判断原始 JSON 是对象还是数组,得看首字符
最轻量、最可靠的方式是直接检查字符串开头:
-
trim($json)[0] === '{'→ 极大概率是 JSON 对象(合法 JSON 中,以{开头且无 BOM 的字符串,基本可断定为对象) -
trim($json)[0] === '['→ 极大概率是 JSON 数组 - 注意先
trim()去除空白和 UTF-8 BOM("\xEF\xBB\xBF"),否则可能取到 BOM 字节而非真实首字符 - 该方法不解析、不报错、不触发
json_last_error(),适合做前置快速分流,比如路由逻辑或日志分类
需要确认「是否为合法 JSON」时,必须用 json_last_error()
仅靠首字符无法验证合法性。比如 "{a:1}" 也以 { 开头,但不是合法 JSON。此时必须走标准流程:
- 调用
json_decode($json, true)(或false,不影响判断) - 立即调用
json_last_error() === JSON_ERROR_NONE - 务必提前排除空或纯空白:
!is_string($json) || trim($json) === '',否则json_decode('')返回null且不报错,json_last_error()仍是JSON_ERROR_NONE,造成误判
解析后想区分“空对象”和“空数组”,别用 empty()
empty([]) 和 empty((object)[]) 都返回 true,但它们语义不同。安全做法是:
立即学习“PHP免费学习笔记(深入)”;
- 若已用
json_decode($json, true)→ 检查is_array($data) && $data === [](空数组)或is_object($data) && get_object_vars($data) === [](空对象) - 若用
json_decode($json, false)→gettype($data) === 'object'且get_object_vars($data) === [] - 避免对
stdClass实例直接调用count(),会触发 warning 并返回0,和解析失败表现一致
json_last_error() 组合覆盖 99% 场景;真正需要深挖结构语义时,才需进一步区分空对象/空数组。多数接口校验或日志打点,首字符就足够快且稳。



















