应先用json_last_error()确认json_decode()解析成功,再用count()测数组长度;若需字节长度用strlen();判断空结构需区分空数组、空对象和解析失败。

json_decode() 后用 count() 测数组长度,但必须先确认是否解析成功
PHP 里不能直接对原始 JSON 字符串用 count()——它只是字符串,count("{'a':1}") 永远返回 1。真正要测的是解析后的数据结构大小。但关键陷阱是:json_decode() 失败时返回 null,而 count(null) 不报错,却静默返回 0,极易掩盖解析失败问题。
- 务必先检查
json_last_error() === JSON_ERROR_NONE或判断返回值是否为array/object - 若期望数组结构,建议加第二个参数
true(即json_decode($json, true)),避免后续对stdClass对象误用count() - 空 JSON 数组
"[]"解析后count()得 0;空对象"{}"得 0;无效 JSON 如"{"则返回null,此时count()也返回 0 —— 看似“长度为 0”,实为解析失败
用 strlen() 测原始 JSON 字符串长度,但要注意编码和 BOM
如果目标就是知道传输或存储的 JSON 文本字节数(比如限长校验、日志记录),strlen() 是最快最准的方式。但它数的是字节,不是字符,且对 UTF-8 中文、emoji 等多字节字符会返回实际字节数(如一个中文通常是 3 字节)。
- 确保输入是纯字符串,不是已解析的对象或数组,否则
strlen([])会触发警告并返回false - 文件读入的 JSON 可能含 UTF-8 BOM(
\xEF\xBB\xBF),导致strlen()比预期多 3,可用ltrim($json, "\xEF\xBB\xBF")预处理 - 不要用
mb_strlen($json, 'UTF-8')替代——它返回字符数,对长度限制类场景(如 API body size 限制)无意义,服务器认的是字节
判断 JSON 是否为空结构:区分 "[]", "{}", null 和 false
业务中常需判断“这个 JSON 数据有没有实质内容”,但 json_decode() 的返回值类型和含义容易混淆:
-
"[]"→json_decode()返回空数组,empty()为true,count()为 0 -
"{}"→ 返回空对象(stdClass),empty()为true,但count()报 warning 并返回 0;应改用get_object_vars($obj) === []或提前转数组 -
""或null或解析失败 → 全部得到null,必须靠json_last_error()区分 - 安全写法:
$data = json_decode($json, true); if (is_array($data) && $data === []) { /* 空数组 */ } elseif (is_object($data) && get_object_vars($data) === []) { /* 空对象 */ }
性能敏感场景:避免重复解析 + 提前短路判断
如果只是想快速知道 JSON 是否“明显过长”或“明显为空”,没必要完整解析再测长度。可结合字符串操作做前置过滤:
立即学习“PHP免费学习笔记(深入)”;
- 用
strlen($json) > 10 * 1024 * 1024快速拦截超大字符串(如 >10MB),省去json_decode()开销 - 用正则
preg_match('/^\s*[\[\{]/', $json)粗略判断是否以[或{开头,排除明显非法开头(但不能替代json_last_error()) - 若只关心数组元素个数,且 JSON 格式严格可控(如无换行、无多余空格),可用
substr_count($json, ',') + 1粗略估算(仅限顶层数组,且逗号在字符串内会误判) - 真实生产环境仍应以
json_decode()+json_last_error()为准,上述技巧仅作快速门禁
JSON 解析后的长度判断,核心矛盾从来不在函数怎么写,而在你到底想测“字节长度”“元素个数”还是“是否为空结构”——三者对应完全不同的代码路径,混用就会在某个凌晨三点收到告警。











