如何将 PHP 处理后的 JSON 保持原始换行与缩进风格(每对象一行)

14次阅读

如何将 PHP 处理后的 JSON 保持原始换行与缩进风格(每对象一行)

本文介绍一种在 php 中手动构造“类原始风格”json 字符串的方法,使其维持 `[` 开头、每个对象独占一行、末尾带 `]` 的可读格式,而非默认的单行紧凑输出。适用于调试或特定格式兼容场景,但不推荐用于生产环境。

php 中,json_encode() 默认生成紧凑、无换行、无空格的 jsON 字符串(如 [{“id”:”1″,”name”:”john”},…]),这虽利于传输与解析,却不便于人工阅读或版本控制比对。而用户原始 json 文件采用的是“类手工排版”风格:数组整体换行包裹,每个对象独立成行、字段间保留空格(如 “id”: “1” 而非 “id”:”1″)。这种格式虽非标准 JSON 规范所强制要求,但在某些编辑场景(如 git diff 友好、配置文件维护)中确有实用价值。

要实现该效果,不能依赖 json_encode() 的内置选项(如 JSON_PRETTY_PRINT 会产生缩进嵌套,不符合“每对象一行”的扁平结构),而需手动拼接:

  1. 确保输入为索引数组(list):使用 array_is_list()(PHP ≥8.1)或自定义 polyfill 判断,避免关联数组导致逻辑错误;
  2. 逐项 json_encode() 每个元素:利用其默认紧凑格式保证单个对象内无额外换行;
  3. 用 implode(“,n”, …) 连接对象:实现逗号+换行分隔;
  4. 手动包裹 [ 和 ] 并添加首尾换行:达成目标结构。

以下是完整、可直接运行的示例代码:

// 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 内含对象),手动拼接将迅速失控;
  • 强烈建议替代方案
    • 生产环境始终使用 json_encode($data, JSON_UNESCAPED_UNICODE) 等标准方式;
    • 查看/编辑时借助命令行工具(如 jq -C ‘.’ input.json | less)或编辑器插件实时美化;
    • 版本控制中可配置 .gitattributes 对 .json 文件启用 diff=json,提升可读性。

总之,该技巧是特定场景下的“权宜之计”,理解其原理有助于规避误用,而拥抱标准工具链才是长期高效之道。

text=ZqhQzanResources