
本文介绍一种安全、可复用的递归遍历方法,用于向已构建的树形部门层级数组中精准插入员工节点,避免子节点覆盖问题,并支持多层嵌套(最高5层),同时保持原始数据不可变。
本文介绍一种安全、可复用的递归遍历方法,用于向已构建的树形部门层级数组中精准插入员工节点,避免子节点覆盖问题,并支持多层嵌套(最高5层),同时保持原始数据不可变。
在基于部门与子部门的树形数据结构中,_children 字段是 Tabulator 等前端组件识别层级关系的关键约定。你已通过 buildHierarchyDepartment() 成功构建了部门树,但直接在递归构建过程中混入员工数据会导致 _children 被部门子树覆盖——因为员工和部门同属“子节点”,却需共存于同一 _children 数组中。
正确的解法是分离关注点:先构建纯净的部门树,再对已有树进行非破坏性遍历插入。以下提供一个健壮、类型安全、支持深度嵌套的 addChild() 工具函数:
function addChild(array $main, array $item, int $parent_id): array
{
$result = [];
foreach ($main as $key => $element) {
// 深拷贝当前节点(确保不可变性)
$node = $element;
// 找到匹配的父节点(严格类型比较,推荐保持 int 一致性)
if ($node['id'] === $parent_id) {
// 初始化 _children 数组(若不存在)
if (!isset($node['_children']) || !is_array($node['_children'])) {
$node['_children'] = [];
}
// 追加新员工(或任意子项)
$node['_children'][] = $item;
}
// 递归处理子树(无论是否命中父节点,均需向下遍历)
if (isset($node['_children']) && is_array($node['_children'])) {
$node['_children'] = addChild($node['_children'], $item, $parent_id);
}
$result[] = $node;
}
return $result;
}✅ 使用示例:
// 假设 $rows 是已构建好的部门树
$employee = [
'id' => 99,
'name' => 'Alice Johnson',
'type' => 'employee', // 可选:便于前端区分部门/员工
'position' => 'Senior Developer',
'parent_id' => 4, // 归属“Four”部门(id=4)
];
// 安全生成新树,不修改原 $rows
$updatedRows = addChild($rows, $employee, $employee['parent_id']);⚠️ 关键注意事项:
-
类型安全:务必确保
$parent_id和$element['id']同为整型(推荐数据库字段定义为INT),避免==引发意外匹配(如'1' == 1为true,但可能混淆业务语义)。 -
不可变设计:函数始终返回新数组,原
$rows不被修改,符合函数式编程原则,便于调试与测试。 - 兼容多层级:递归逻辑自动穿透任意深度(如 5 层部门链),无需手动展开循环。
-
健壮性增强:显式检查
_children是否为数组,防止因数据异常(如null或字符串)导致崩溃。 -
扩展建议:若需批量添加员工,可将
$item改为数组,内部遍历追加;若需按顺序插入(如首/尾),可替换[]=为array_unshift()或自定义位置逻辑。
该方案彻底解耦了“结构构建”与“内容填充”,既复用已有部门树逻辑,又为后续动态增删员工、岗位、设备等各类子节点提供了统一、可扩展的插入接口。

















