PHP递归遍历未知深度数组时父键无法深层保留的问题求助
解决多维数组递归遍历后的嵌套结构问题
你的问题核心在于原递归函数只是将每个节点的结果独立存入了对应父ID的顶级键中,没有把子节点的结构嵌套到父节点的数组内部。这里提供两种可行的解决方案,先看最直观的一种:
方案一:通过引用传递父节点数组(推荐)
这种方法直接在递归过程中维护嵌套关系,让子节点直接挂载到父节点的结构里,逻辑更清晰:
function traverse(array $entries, array &$parentArray) { foreach ($entries as $entry) { // 处理当前节点的逻辑规则(替换成你的实际业务逻辑) $currentNode = ['logic_rules' => time()]; // 将当前节点添加到父数组中,用节点ID作为键 $parentArray[$entry['id']] = &$currentNode; // 如果存在子节点,递归遍历并将当前节点作为父数组传递 if (isset($entry['children'])) { traverse($entry['children'], $currentNode); } // 释放引用,避免后续遍历出现引用混乱 unset($currentNode); } } // 初始化最终结果,以root作为顶级父节点 $finalResult = ['root' => []]; traverse($entries, $finalResult['root']); print_r($finalResult);
思路说明:
- 不再用全局的
$result存储分散的父节点,而是通过引用传递当前父节点的数组,让子节点直接嵌套到父节点内部。 - 每个节点先创建自身结构并加入父数组,再把自身结构作为父数组传给子节点的递归调用,子节点会自动嵌套进来。
- 最后释放引用是为了避免后续循环中意外修改已处理的节点。
方案二:先扁平化处理再组装嵌套结构
如果不想使用引用,也可以先遍历生成扁平映射,再根据父ID关系组装成嵌套结构:
function traverseFlat(array $entries, array &$flatMap = []) { foreach ($entries as $entry) { // 处理当前节点逻辑 $flatMap[$entry['id']] = ['logic_rules' => time()]; // 递归处理子节点,存入扁平映射 if (isset($entry['children'])) { traverseFlat($entry['children'], $flatMap); // 把子节点的结构合并到父节点中 foreach ($entry['children'] as $child) { $flatMap[$entry['id']][$child['id']] = &$flatMap[$child['id']]; } } } return $flatMap; } // 生成扁平映射 $flatMap = traverseFlat($entries); // 组装最终的root嵌套结构 $finalResult = ['root' => []]; foreach ($entries as $entry) { if ($entry['parent'] === 'root') { $finalResult['root'][$entry['id']] = $flatMap[$entry['id']]; } } print_r($finalResult);
思路说明:
- 先遍历所有节点,把每个节点的结果存入以ID为键的扁平数组
$flatMap。 - 处理子节点时,将子节点的引用合并到父节点的结构中。
- 最后从
$flatMap中提取所有parent为root的节点,组装成顶级嵌套结构。
两种方案运行后都能得到你预期的嵌套输出结构,方案一更高效且逻辑更简洁,推荐使用。
内容的提问来源于stack exchange,提问作者metad00r
相关产品推荐
相关产品推荐

