
在web开发中,处理具有层级关系的数据是一项常见任务,例如网站导航菜单、商品分类、评论回复、组织架构等。这类数据通常以扁平化的形式存储在数据库中,每条记录包含一个id和一个指向其父级记录的id(parentid)。然而,在前端展示或进行某些业务逻辑处理时,我们往往需要将这种扁平数据转换为嵌套的树形结构。
例如,我们可能有如下的扁平化数据:
$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']
];我们期望将其转换为如下的嵌套结构,其中子元素通过 pages 键包含:
$index = [
[
'id' => 1,
'pages' => [
[
'id' => 2,
'pages' => [
[
'id' => 3
]
]
]
]
]
];递归是一种函数或过程调用自身的编程技术。在处理树形结构数据时,递归表现出其天然的优势。构建树形结构的过程可以被分解为:找到当前父节点的所有直接子节点,然后对每个子节点重复相同的过程(即找到它们的子节点),直到没有更多的子节点为止。这正是递归思想的完美应用场景。
我们将创建一个名为 buildSubs 的函数,它接收两个参数:完整的扁平化数据数组 $elms 和当前要查找的父ID $parentId。
立即学习“PHP免费学习笔记(深入)”;
为了构建完整的树形结构,我们需要从根节点开始。在我们的示例数据中,根节点的 parentid 是 0。因此,在第一次调用 buildSubs 函数时,$parentId 应该设置为 0。
<?php
/**
* 递归函数:将扁平化数组转换为树形结构
*
* @param array $elms 包含所有元素的扁平化数组
* @param int $parentId 当前要查找的父ID
* @return array 构建好的树形分支
*/
function buildSubs(array $elms, int $parentId = 0): array
{
$branch = []; // 用于存放当前父ID下的直接子元素
foreach ($elms as $key => $elm) { // 遍历所有元素
if ($elm['parentid'] == $parentId) { // 如果当前元素的parentid匹配目标parentId
// 递归调用自身,查找当前元素的子元素
$children = buildSubs($elms, $elm['id']);
// 如果存在子元素,则将其添加到当前元素的 'pages' 键中
if (!empty($children)) {
$elm['pages'] = $children; // 核心修正:修改 $elm 而非 $elms
}
// 将处理好的元素(可能已包含子树)添加到当前分支
$branch[] = $elm;
// 优化:从原数组中移除已处理的元素,减少后续遍历的范围 (可选,但对于大型数据集有性能优势)
// unset($elms[$key]); // 注意:如果使用此行,递归调用时需要传递引用或重新考虑逻辑
}
}
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>';
?>执行上述代码后,var_dump($tree) 将输出以下结果,这正是我们期望的树形结构:
Array
(
[0] => Array
(
[id] => 1
[parentid] => 0
[route] => root
[title] => root
[pages] => Array
(
[0] => Array
(
[id] => 2
[parentid] => 1
[route] => parent
[title] => parent
[pages] => Array
(
[0] => Array
(
[id] => 3
[parentid] => 2
[route] => child
[title] => child
)
)
)
)
)
)通过本教程,我们学习了如何利用PHP的递归功能将扁平化的父子关系数据转换为易于处理和展示的树形结构。理解递归的核心逻辑、正确处理当前元素的修改以及从正确的根节点开始构建是实现这一转换的关键。虽然递归在处理树形数据时非常优雅,但在面对大规模数据时也需要考虑其性能和内存影响,并根据实际需求选择最合适的实现方案。
以上就是PHP递归实现扁平数组到树形结构的转换的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号