PHP利用引用关系实现无限分类树形数组

Leo
Leo
发布时间:2026-10-14 | 6人浏览过
原创

在处理数据库中的无限分类(如多级菜单、目录结构)时,传统递归方法在数据量大时性能较差。本文将分享一种基于引用关系的迭代方法,无需递归即可将扁平的邻接表数据高效转换为具有父子层级关系的树形数组。

核心原理与实现

PHP 提供了强大的引用赋值特性。我们可以通过两次遍历数组,一次建立主键索引,另一次利用引用直接将子节点挂载到父节点或父节点关联到子节点,从而构建出完整的树形结构。

以下是两个关键函数:find_parent 用于创建包含父节点引用的树,find_child 用于创建包含子节点引用的树。

第1步:定义构建子节点树形的函数 find_child

目的: 将线性数据转换为以“子节点”为视角的嵌套树状数组。

代码实现:

/**
 * 创建子节点树形数组
 * @param array $ar 邻接列表方式组织的数据
 * @param string $id 主键字段名
 * @param string $pid 父键字段名
 * @return array 多维数组
 */
function find_child($ar, $id='id', $pid='pid') {
    // 第一步:将所有元素按 ID 索引存储,方便 O(1) 查找
    foreach($ar as $v) $t[$v[$id]] = $v;
    
    // 第二步:遍历所有项,如果该项有父级ID,且该父级存在
    foreach ($t as $k => $item){
        if( $item[$pid] ) {
            // 将当前项作为引用,挂载到父项的 'child' 键下
            $t[$item[$pid]]['child'][$item[$id]] =& $t[$k];
        }
    }
    return $t;
}

第2步:定义构建父节点树形的函数 find_parent

目的: 以“父节点”为视角,为每个节点添加其直接父节点的引用,便于自底向上追溯路径。

代码实现:

/**
 * 创建父节点树形数组
 * @param array $ar 邻接列表方式组织的数据
 * @param string $id 主键字段名
 * @param string $pid 父键字段名
 * @return array 多维数组
 */
function find_parent($ar, $id='id', $pid='pid') { 
    // 第一步:将所有元素按 ID 索引存储
    foreach($ar as $v) $t[$v[$id]] = $v;
    
    // 第二步:遍历所有项,如果该项有父级ID,且该父级存在
    foreach ($t as $k => $item){
        if( $item[$pid] ){
            // 将父项作为引用,存入当前项的 'parent' 键中
            // 注意:这里使用数组索引防止同名覆盖,实际应用中可根据需求调整
            if( ! isset($t[$item[$id]]['parent'][$item[$pid]]) )
                $t[$item[$id]]['parent'][$item[$pid]] =& $t[$item[$pid]];
        }
    } 
    return $t;
}

实际应用示例

假设我们有一组从数据库读取的邻接表数据,结构如下:

$data = array(
    array('ID'=>1, 'PARENT'=>0, 'NAME'=>'祖父'),
    array('ID'=>2, 'PARENT'=>1, 'NAME'=>'父亲'),
    array('ID'=>3, 'PARENT'=>1, 'NAME'=>'叔伯'),
    array('ID'=>4, 'PARENT'=>2, 'NAME'=>'自己'),
    array('ID'=>5, 'PARENT'=>4, 'NAME'=>'儿子'),
);

调用上述函数进行测试:

$p = find_parent($data, 'ID', 'PARENT');
$c = find_child($data, 'ID', 'PARENT');

执行效果说明:

以 find_child 为例,返回的数组结构如下(简化示意):

  • ID 1 (祖父) 的数组中包含 'child' 键,指向 ID 2 和 ID 3
  • ID 2 (父亲) 的数组中包含 'child' 键,指向 ID 4
  • ID 4 (自己) 的数组中包含 'child' 键,指向 ID 5

这种结构非常适合前端渲染树形菜单或目录。由于使用了引用 (&),内存中只存在一份数据副本,极大节省了内存开销。需要注意的是,修改树中的一个节点内容,会通过引用影响整个树结构的相关部分,因此在最后一步通常需要使用 array_values() 重新索引或直接使用各根节点。

总结

利用 PHP 引用特性进行迭代式树构建,比递归更高效且避免了深层调用栈风险。对于常见的后台管理系统的无限极分类功能,这是一种经典且实用的解决方案。以上就是利用引用关系在PHP中实现无限分类树形数组的详细内容,更多关于PHP高级编程技巧的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表