json_decode()返回null主因是JSON字符串非法或编码错误,需先用mb_detect_encoding检查UTF-8,再用json_last_error()定位具体错误类型,如语法、UTF-8或深度问题。

json_decode() 返回 null 怎么办
PHP 里用 json_decode() 解析 JSON 字符串却得到 null,八成是原始字符串本身不合法,或者编码不对。不是分割的问题,是压根没解出来。
先确认输入是否为干净的 UTF-8 字符串:用 mb_detect_encoding($json, ['UTF-8'], true) 检查;若返回 false 或不是 UTF-8,得先转码,比如 mb_convert_encoding($json, 'UTF-8', 'GBK')(根据源编码调整)。
再用 json_last_error() 和 json_last_error_msg() 看具体错在哪:
-
JSON_ERROR_SYNTAX:常见于换行、多余逗号、单引号代替双引号、BOM 头 -
JSON_ERROR_UTF8:字符串含非法 UTF-8 字节,trim($json)或preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $json)可清理控制字符 -
JSON_ERROR_DEPTH:嵌套太深,可调ini_set('memory_limit', '256M')或改递归逻辑
想按行分割 JSON 数组?别直接 explode("\n")
很多人把多行 JSON(比如每行一个对象)当成纯文本用 explode("\n", $content) 切,结果某一行 JSON 含换行符(如字符串值里有 \n),就切歪了——这不是分割策略问题,是格式认知错误。
立即学习“PHP免费学习笔记(深入)”;
正确做法分两种场景:
- 如果是 JSON Lines 格式(每行一个独立 JSON 对象),用
file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)读行,再对每行单独json_decode() - 如果是 标准 JSON 数组(
[{...},{...}]),根本不需要按行分割,直接json_decode($content, true)得到 PHP 数组,再用array_chunk()或循环处理
强行用 str_split() 或正则切 JSON 结构,大概率破坏嵌套结构,导致解析失败。
json_decode() 后怎么安全分割数据
解码成功后得到数组或对象,分割逻辑就变成 PHP 原生操作,和 JSON 无关了。关键看你要“分割”什么:
- 按数量分块:用
array_chunk($data, 100) - 按字段值分流:比如
array_filter($data, fn($item) => $item['status'] === 'active') - 按键名提取子集:用
array_column($data, 'name')或array_map(fn($x) => $x['id'], $data)
注意:json_decode($json, false) 返回对象,不能用数组函数直接操作;必须加第二个参数 true 才返回关联数组,否则会报 Warning: Illegal string offset 这类错误。
大文件 JSON 解析内存爆掉?得流式处理
几百 MB 的 JSON 文件,用 file_get_contents() + json_decode() 必崩。这时候“先解码再分割”本身就不成立——你根本加载不完。
可行方案只有两个:
- 用
JsonStreamingParser类库(如 sahilgupta/json-streaming-parser),边读边解析,逐个处理对象,不全量入内存 - 预处理:用命令行工具(如
jq -c '.[]' huge.json > lines.jsonl)转成 JSON Lines,再用 PHP 逐行读取
别试图用 fgets() 自己“跳括号”来模拟流式解析——JSON 结构嵌套任意深度,手动匹配 {/} 极易出错,且无法处理转义、注释(虽然标准 JSON 不该有)、字符串内嵌等边界情况。











