如何在 PHP 中将 JSON 数组保持“每行一个对象”的可读格式重新序列化

如何在 PHP 中将 JSON 数组保持“每行一个对象”的可读格式重新序列化

本文介绍一种绕过标准 `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]}
]

⚠️ 注意事项:

Designs.ai

Designs.ai

AI设计工具

下载

立即学习PHP免费学习笔记(深入)”;

  • 此格式不等价于 JSON_PRETTY_PRINT —— 它不处理嵌套对象/数组的缩进,仅保证顶层对象独占一行;
  • json_encode() 默认会对中文、斜杠等转义,我们通过 JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES 保持原始可读性;
  • 切勿用于生产环境的数据交换:标准 JSON 解析器均能正确处理该格式,但人为干预序列化逻辑易引入歧义,应优先使用标准格式 + 外部工具(如 jq ‘.’ file.json)做可视化美化;
  • 若输入含关联数组(键名非数字连续),函数将抛出异常,确保数据结构可控。

总结:该方案是权衡可读性与实现简易性的折中选择,核心思想是「解码 → 变更 → 单项编码 → 手动组装」。真正健壮的工程实践,仍是坚持标准 JSON 格式,并将格式化职责交给专用工具或前端渲染层。

https://www.php.cn/faq/1983080.html

发表回复

Your email address will not be published. Required fields are marked *