如何为多维嵌套数组的每个子元素自动添加 parent_id 字段

如何为多维嵌套数组的每个子元素自动添加 parent_id 字段

本文介绍在 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);

关键要点说明:

聚蜂消防BeesFPD

聚蜂消防BeesFPD

关注消防领域的智慧云平台

下载

  • 使用 &$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 处理层级数据标准化预处理的推荐实践。

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

发表回复

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