
本文介绍在 php 中递归遍历多维嵌套数组(如树形结构),为每个非根节点的子元素动态注入 `parent_id` 字段,使其准确指向其直接父节点的 `uuid`,适用于菜单、组织架构、分类体系等场景。
在处理树状数据结构(例如带 childrens 嵌套的层级菜单或部门树)时,常需将扁平化关系显式表达为父子引用。原始数据仅含各节点自身的 uuid,而子节点缺少对其父节点 ID 的显式声明。此时,可通过递归函数自上而下传递父级 uuid,并在每一层子节点中添加 parent_id 键。
以下是一个简洁、健壮的实现方案:
function addParentId(&$nodes, $parentId = null) {
foreach ($nodes as &$node) {
// 若存在父 ID,则写入 parent_id 字段
if ($parentId !== null) {
$node->parent_id = $parentId;
}
// 递归处理子节点,当前节点的 uuid 成为子节点的 parent_id
if (isset($node->childrens) && is_array($node->childrens) && !empty($node->childrens)) {
addParentId($node->childrens, $node->uuid);
}
}
}
// 示例数据(JSON 字符串)
$json = '{
"array": [
{
"uuid": 7,
"nome": "Parent",
"ativo": 1,
"childrens": [
{
"uuid": 9,
"nome": "Child",
"ativo": 1,
"childrens": [
{
"uuid": 70,
"nome": "Child of Child",
"ativo": 1,
"childrens": [
{
"uuid": 391,
"nome": "Child of Child of Child",
"ativo": 1,
"childrens": []
}
]
}
]
}
]
}
]
}';
$object = json_decode($json);
// 从顶层 array 开始遍历:每个顶级元素无 parent_id,其 childrens 的 parent_id = 顶级 uuid
foreach ($object->array as $elem) {
if (!empty($elem->childrens)) {
addParentId($elem->childrens, $elem->uuid);
}
}
echo json_encode($object, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);✅ 关键要点说明:
- 使用 &$nodes 引用传参,确保修改直接作用于原对象,避免复制开销;
- parent_id 仅在子节点层级写入(根节点不设 parent_id),符合语义逻辑;
- 函数兼容任意深度嵌套,且对空 childrens 或缺失字段具备容错性(通过 isset() 和 is_array() 判断);
- 支持中文字符(JSON_UNESCAPED_UNICODE)和格式化输出,便于调试。
⚠️ 注意事项:
- 若原始数据为关联数组([] 而非 stdClass 对象),需将 json_decode($json, true) 改为 false(默认),或改用数组语法(如 $node['parent_id'] = $parentId);
- 在大规模数据场景中,可考虑迭代替代递归以规避栈溢出风险;
- 若需反向构建(如从 parent_id 重建树),应另设计映射索引逻辑,本方案不覆盖该需求。
该方法轻量、可复用,是 PHP 处理层级数据标准化预处理的推荐实践。










