
本文介绍一种绕过标准 `json_encode()` 默认紧凑格式的方法,通过手动拼接实现类似原始输入的“换行分隔、缩进一致”的 json 数组输出风格,适用于调试或特定格式兼容场景。
在 php 中,默认的 json_encode() 会将整个 json 数据压缩为单行(如 [{“id”:”1″,”name”:”john”},…]),而开发过程中常需保留类似原始编辑时的“多行、每对象一行、无额外缩进”的可读格式(即:[n{“id”: “1”, …},n{“id”: “2”, …}n])。这种格式虽非标准 JSON 规范所强制要求,但在日志记录、配置文件生成或与某些遗留工具交互时仍具实用价值。
关键在于:不依赖 JSON_PRETTY_PRINT(它会添加缩进和嵌套换行,导致结构混乱),而是对已解码的数组逐项 json_encode() 后手动用换行符连接。以下是推荐实现:
// PHP < 8.1 兼容:判断是否为索引列表(非关联数组) if (!function_exists('array_is_list')) { function array_is_list(array $a): bool { return $a === [] || (array_keys($a) === range(0, count($a) - 1)); } } /** * 将索引数组编码为「每对象一行」的 JSON 字符串(无缩进,仅换行分隔) * 示例输出:[n{"id":"1","name":"john"},n{"id":"2","name":"bill"}n] */ function json_encode_oneline_per_item(array $data): string { if (!array_is_list($data)) { throw new InvalidArgumentException('Input must be a sequential (non-associative) array'); } $encodedItems = array_map(fn($item) => json_encode($item, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), $data); return "[n" . implode(",n", $encodedItems) . "n]"; } // 使用示例 $json_text = ' [ {"id": "1", "name": "john", "bd": []}, {"id": "2", "name": "gary", "bd": [1, 2]} ]'; $data = json_decode($json_text, true); // 修改数据(如更新姓名) $data[1]['name'] = 'bill'; // 重新生成目标格式 $formattedJson = json_encode_oneline_per_item($data); echo $formattedJson;
✅ 输出效果:
[ {"id":"1","name":"john","bd":[]}, {"id":"2","name":"bill","bd":[1,2]} ]
⚠️ 注意事项:
立即学习“PHP免费学习笔记(深入)”;
- 此格式不等价于 JSON_PRETTY_PRINT —— 它不处理嵌套对象/数组的缩进,仅保证顶层对象独占一行;
- json_encode() 默认会对中文、斜杠等转义,我们通过 JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES 保持原始可读性;
- 切勿用于生产环境的数据交换:标准 JSON 解析器均能正确处理该格式,但人为干预序列化逻辑易引入歧义,应优先使用标准格式 + 外部工具(如 jq ‘.’ file.json)做可视化美化;
- 若输入含关联数组(键名非数字连续),函数将抛出异常,确保数据结构可控。
总结:该方案是权衡可读性与实现简易性的折中选择,核心思想是「解码 → 变更 → 单项编码 → 手动组装」。真正健壮的工程实践,仍是坚持标准 JSON 格式,并将格式化职责交给专用工具或前端渲染层。