
在web开发中,我们经常会遇到需要处理具有层级关系的数据,例如菜单导航、评论回复、组织架构或文件目录等。这类数据在数据库中通常以扁平化的形式存储,即每条记录包含一个id和指向其父级记录的parentid。然而,为了更好地在前端展示或进行逻辑处理,我们往往需要将这种扁平结构转换为嵌套的树形结构。递归是解决此类问题的强大工具。
递归是一种函数调用自身的技术。在构建树形结构时,递归的核心思想是:
假设我们有以下扁平化的数组数据,其中每个元素包含id、parentid、route和title:
$indexes = [
['id' => 1, 'parentid' => 0, 'route' => 'root', 'title' => 'root'],
['id' => 2, 'parentid' => 1, 'route' => 'parent', 'title' => 'parent'],
['id' => 3, 'parentid' => 2, 'route' => 'child', 'title' => 'child']
];我们期望通过处理,得到一个嵌套的树形结构,例如:
$index = [
[
'id' => 1,
'parentid' => 0,
'route' => 'root',
'title' => 'root',
'pages' => [
[
'id' => 2,
'parentid' => 1,
'route' => 'parent',
'title' => 'parent',
'pages' => [
[
'id' => 3,
'parentid' => 2,
'route' => 'child',
'title' => 'child'
]
]
]
]
]
];以下是用于构建树形结构的buildSubs函数,并对其关键部分进行解析:
立即学习“PHP免费学习笔记(深入)”;
<?php
function buildSubs(array $elms, int $parentId = 0)
{
$branch = []; // 用于存储当前parentId下的所有直接子元素
foreach ($elms as $elm) {
// 检查当前元素的parentid是否与传入的parentId匹配
if ($elm['parentid'] == $parentId) {
// 递归调用自身,查找当前元素的子元素
// 将当前元素的ID作为新的parentId传入
$children = buildSubs($elms, $elm['id']);
// 如果找到了子元素,则将它们添加到当前元素的'pages'键下
// 注意:这里必须使用 $elm['pages'] 而不是 $elms['pages']
// $elm 指的是当前循环中的单个元素,而 $elms 是原始的完整数组
if ($children) {
$elm['pages'] = $children;
}
// 将处理后的当前元素(可能包含其子元素)添加到当前分支
$branch[] = $elm;
}
}
// 返回当前parentId下的所有直接子元素及其递归构建的后代
return $branch;
}
// 原始扁平数据
$indexes = [
['id' => 1, 'parentid' => 0, 'route' => 'root', 'title' => 'root'],
['id' => 2, 'parentid' => 1, 'route' => 'parent', 'title' => 'parent'],
['id' => 3, 'parentid' => 2, 'route' => 'child', 'title' => 'child']
];
// 调用函数构建树形结构
// 为了获取完整的树,通常从根节点的parentId(例如0)开始
$tree = buildSubs($indexes, 0);
// 输出结果
echo "<pre>";
var_dump($tree);
echo "</pre>";
?>关键修正点:$elm['pages'] = $children;
原始代码中可能存在的错误是使用了$elms['pages'] = $children;。这是一个常见的混淆点:
为了构建完整的树形结构,我们需要从根节点开始调用buildSubs函数。通常,根节点的parentid会被设置为一个特殊值,例如0或null。在我们的例子中,根节点的parentid是0。
$tree = buildSubs($indexes, 0);
运行上述代码,将得到如下的树形结构输出:
array(1) {
[0]=>
array(5) {
["id"]=>
int(1)
["parentid"]=>
int(0)
["route"]=>
string(4) "root"
["title"]=>
string(4) "root"
["pages"]=>
array(1) {
[0]=>
array(5) {
["id"]=>
int(2)
["parentid"]=>
int(1)
["route"]=>
string(6) "parent"
["title"]=>
string(6) "parent"
["pages"]=>
array(1) {
[0]=>
array(4) {
["id"]=>
int(3)
["parentid"]=>
int(2)
["route"]=>
string(5) "child"
["title"]=>
string(5) "child"
}
}
}
}
}
}通过本教程,我们学习了如何使用PHP递归函数将扁平化的父子关系数据转换为嵌套的树形结构。掌握这种技术对于处理各种层级数据至关重要。正确理解递归的原理,特别是对循环变量和作用域的把握,是成功实现此类功能的关键。
以上就是PHP递归构建树形结构数组:从扁平数据到嵌套层级的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号