
本文介绍一种在 php 中手动构造“类原始风格”json 字符串的方法,使其维持 `[` 开头、每个对象独占一行、末尾带 `]` 的可读格式,而非默认的单行紧凑输出。适用于调试或特定格式兼容场景,但不推荐用于生产环境。
在 php 中,json_encode() 默认生成紧凑、无换行、无空格的 jsON 字符串(如 [{“id”:”1″,”name”:”john”},…]),这虽利于传输与解析,却不便于人工阅读或版本控制比对。而用户原始 json 文件采用的是“类手工排版”风格:数组整体换行包裹,每个对象独立成行、字段间保留空格(如 “id”: “1” 而非 “id”:”1″)。这种格式虽非标准 JSON 规范所强制要求,但在某些编辑场景(如 git diff 友好、配置文件维护)中确有实用价值。
要实现该效果,不能依赖 json_encode() 的内置选项(如 JSON_PRETTY_PRINT 会产生缩进嵌套,不符合“每对象一行”的扁平结构),而需手动拼接:
- 确保输入为索引数组(list):使用 array_is_list()(PHP ≥8.1)或自定义 polyfill 判断,避免关联数组导致逻辑错误;
- 逐项 json_encode() 每个元素:利用其默认紧凑格式保证单个对象内无额外换行;
- 用 implode(“,n”, …) 连接对象:实现逗号+换行分隔;
- 手动包裹 [ 和 ] 并添加首尾换行:达成目标结构。
以下是完整、可直接运行的示例代码:
// PHP < 8.1 兼容 polyfill if (!function_exists('array_is_list')) { function array_is_list(array $a): bool { return $a === [] || (array_keys($a) === range(0, count($a) - 1)); } } function formatJsonAsOneLinePerItem(array $data): string { if (!array_is_list($data)) { throw new InvalidArgumentException('Input must be a sequential array (list).'); } $encodedItems = array_map(fn($item) => json_encode($item), $data); return "[n" . implode(",n", $encodedItems) . "n]"; } // 示例使用 $json_text = ' [ {"id": "1", "name": "john", "bd": []}, {"id": "2", "name": "gary", "bd": [1, 2]} ]'; $decoded = json_decode($json_text, true); // 修改数据(如更新姓名) $decoded[1]['name'] = 'bill'; // 重新格式化为原始风格 $result = formatJsonasOneLinePerItem($decoded); echo $result;
输出结果严格匹配需求:
立即学习“PHP免费学习笔记(深入)”;
[ {"id":"1","name":"john","bd":[]}, {"id":"2","name":"bill","bd":[1,2]} ]
⚠️ 重要注意事项:
- 此方法生成的 JSON 完全合法(符合 RFC 8259),空格与换行在 JSON 中是允许的空白字符,不影响解析;
- 但它牺牲了可维护性与健壮性:一旦数据结构嵌套加深(如 bd 内含对象),手动拼接将迅速失控;
- 强烈建议替代方案:
总之,该技巧是特定场景下的“权宜之计”,理解其原理有助于规避误用,而拥抱标准工具链才是长期高效之道。