1. 场景分析与目标
示例数据结构
在实际开发中,PHP对象数组往往包含若干字段,其中我们常常只需要其中的部分属性来构成一个简洁的 JSON 数据。目标是:从对象数组中提取指定属性,并将结果转成 JSON 字符串以供前端使用或 API 返回。
例如,你可能有一个对象数组,每个对象具备 id、name、email 等属性,但前端只需要 id 和 name。这时,应该只保留这两项属性来输出 JSON。
下面给出一个简单的示例数据结构,帮助理解要处理的对象数组如何转化为目标 JSON:
1, 'name' => '张三', 'email' => 'zhang@example.com'],(object) ['id' => 2, 'name' => '李四', 'email' => 'li@example.com'],
];
?>
在上述场景中,输出的 JSON 应仅包含 id 与 name,以减少传输数据量并提升前后端对接的清晰度。
[{"id":1,"name":"张三"},{"id":2,"name":"李四"}]2. 步骤一:直接使用 array_map 提取属性
核心思路
第一步的思路非常直接:使用 array_map 遍历对象数组,对每个对象提取所需的属性,组装成新的数组结构,再统一转成 JSON。
核心方法是在回调中只返回需要的字段,避免输出整个对象结构,从而得到一个新的数组,随后用 json_encode 转换为字符串。
下面给出一个完整的演示代码,展示如何从对象数组中提取 id 与 name,并输出 JSON 字符串:
$u->id, 'name' => $u->name];
}, $users);$json = json_encode($selected, JSON_UNESCAPED_UNICODE);
echo $json;
?>
上述方法的输出与目标 JSON 一致,简洁且高效,适用于字段固定且结构简单的场景。
[{"id":1,"name":"张三"},{"id":2,"name":"李四"}]3. 使用 JsonSerializable 提升可维护性
实现方法
当对象本身来自自定义类时,可以通过实现 JsonSerializable 来控制 JSON 的序列化输出。这种方式能够在对象内部定义需要输出的字段,便于在多处场景复用。
实现示例:定义一个 User 类,让它实现 JsonSerializable,并在 jsonSerialize 中返回需要的键值对:
id = $id;$this->name = $name;$this->email = $email;}public function jsonSerialize() {// 仅输出需要的字段return ['id' => $this->id, 'name' => $this->name];}
}$users = [new User(1, '张三', 'zhang@example.com'),new User(2, '李四', 'li@example.com'),
];echo json_encode($users, JSON_UNESCAPED_UNICODE);
?>
通过 实现 JsonSerializable,你可以在不同的场景中复用同一对象,同时确保输出的一致性与可控性。
[{"id":1,"name":"张三"},{"id":2,"name":"李四"}]4. 处理缺失属性与健壮性
保护属性的存在性
在实际对象数组中,某些对象可能缺失某些属性。为了避免运行时错误或输出错位,需要在提取属性时进行健壮性检查,通常采用 isset 与 property_exists 等方法。
下面是一个带有健壮性检查的示例,确保即使某些对象缺失属性,也能得到稳定的输出:

property_exists($u, 'id') ? $u->id : null,'name' => isset($u->name) ? $u->name : null];
}, $users);echo json_encode($selected, JSON_UNESCAPED_UNICODE);
?>
在输出阶段使用 JSON_UNESCAPED_UNICODE 能避免中文被转义,保持 JSON 的可读性。
[{"id":1,"name":"张三"},{"id":2,"name":"李四"}]5. 将对象数组转换为多层结构时的注意事项
递归映射与辅助函数
若对象中存在嵌套结构,需要在映射阶段进行递归处理或通过辅助函数统一生成目标字段。此时可以编写一个通用的 pick 函数,用于选择若干字段,并在需要时组合成多层结构。
示例中,提供一个简单的辅助函数,随后对每个对象提取指定字段,并组装成一个嵌套结构:
$k : null;}return $res;
}$selected = array_map(function($u){return ['id' => $u->id ?? null,'profile' => ['name' => $u->name ?? null,'email' => $u->email ?? null]];
}, $users);echo json_encode($selected, JSON_UNESCAPED_UNICODE);
?>
通过这种方式,你可以灵活控制输出结构,同时保持对原始对象字段的严格约束。若后续字段需求变化,只需要在映射逻辑中进行少量改动即可,降低耦合。
[{"id":1,"profile":{"name":"张三","email":"zhang@example.com"}},{"id":2,"profile":{"name":"李四","email":"li@example.com"}}] 

