php解析多条json需先识别格式:json lines须按行分割后逐解码,json数组可直接解码,拼接无分隔则非法需正则拆分;解码后应立即检查返回值及错误码,避免误用json_last_error_msg();大文件宜流式读取防内存溢出;中文乱码须逐行检测并转换编码,清除bom头。

PHP 里用 json_decode() 解析多条 JSON 数据前先确认格式
不是所有“多条 JSON”都长得一样——常见有三种结构:换行分隔的 JSON Lines、包裹在数组里的 JSON 字符串、纯文本拼接无分隔。错认格式会导致 json_decode() 只解析第一条或直接返回 null。
- JSON Lines(每行一个独立 JSON):
{"id":1,"name":"a"}\n{"id":2,"name":"b"}→ 必须按行切分再逐个json_decode() - JSON 数组:
[{"id":1},{"id":2}]→ 直接json_decode($str, true)得到 PHP 数组,最省事 - 拼接无分隔:
{"id":1}{"id":2}→ 这是非法 JSON,json_decode()必定失败,得先用正则或状态机拆开
循环处理时别在每次迭代里重复调用 json_last_error_msg()
json_last_error_msg() 返回的是最近一次 json_decode() 或 json_encode() 的错误,不是当前循环项的。如果某次解码失败但没检查返回值,后续调用 json_last_error_msg() 会掩盖真实出错位置。
- 正确做法:每次
json_decode()后立刻判断返回值是否为null,且json_last_error() === JSON_ERROR_NONE - 错误示例:
$data = json_decode($line); if (json_last_error() !== JSON_ERROR_NONE) { ... }—— 前面如果有其他 JSON 操作,这里就不可靠 - 批量场景下建议封装校验函数,比如
safe_json_decode($json),内部做判空 + 错误码双检
大批量 JSON 解析时注意内存和性能边界
用 file() 读大文件再 foreach,或一次性 file_get_contents() 加 explode("\n"),都可能把整个文件载入内存。10MB 的 JSON Lines 文件轻松吃掉 50MB+ 内存(PHP 字符串复制 + 解析开销)。
- 超 1MB 的文件优先用
fopen()+fgets()流式读取,边读边解码 - 避免在循环里拼接结果数组:
$all[] = $item;在大数据量下比预分配数组慢 2–3 倍 - 如果只是过滤或转换,考虑用
yield返回 Generator,下游按需消费,不囤积中间数据
中文字段乱码?重点查 mb_detect_encoding() 和 iconv() 的时机
JSON 标准要求 UTF-8 编码,但实际输入可能混着 GBK、UTF-8-BOM、甚至部分字段是 ISO-8859-1。PHP 的 json_decode() 遇到非 UTF-8 字节会静默失败(返回 null),不会报编码错误。
立即学习“PHP免费学习笔记(深入)”;
- 先用
mb_detect_encoding($line, ['UTF-8', 'GBK', 'BIG5'], true)粗判编码,再用iconv()转成 UTF-8 - 不要对整个大字符串转码后再
json_decode()—— 失败时定位困难;应针对每条记录单独检测+转换 - BOM 头必须清除:
ltrim($line, "\xEF\xBB\xBF"),否则json_decode()直接返回null
var_dump(strlen($line), mb_strlen($line, 'UTF-8'), json_last_error()) 比查文档快。











