导读:本期聚焦于小伙伴创作的《PHP怎么用递归处理数据库返回的多层查询结果》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《PHP怎么用递归处理数据库返回的多层查询结果》有用,将其分享出去将是对创作者最好的鼓励。

在PHP开发中,很多业务场景的数据库表会采用父子ID关联的方式存储多层数据,比如商品分类、部门架构等,查询后得到的是所有记录的平铺数组,需要转换成嵌套的树形结构才能方便后续使用,递归就是处理这类问题的常用有效方法。

PHP怎么用递归处理数据库返回的多层查询结果

递归处理的核心思路

递归处理多层查询结果的核心是先找到所有顶层节点,再对每个顶层节点递归查找其下属的子节点,直到没有更多子节点为止。要实现这个逻辑,首先需要有明确的数据结构约定,通常数据库表中需要有id(唯一标识)和parent_id(父节点ID)两个字段,顶层节点的parent_id一般设为0或者null。

基础递归实现示例

以下代码演示了如何将平铺的数据库结果集转换成树形结构,假设已经从数据库查询得到了所有分类数据:

<?php
// 模拟从数据库查询得到的平铺分类结果集
$categoryList = [
    ['id' => 1, 'name' => '电子产品', 'parent_id' => 0],
    ['id' => 2, 'name' => '手机', 'parent_id' => 1],
    ['id' => 3, 'name' => '电脑', 'parent_id' => 1],
    ['id' => 4, 'name' => '智能手机', 'parent_id' => 2],
    ['id' => 5, 'name' => '办公用品', 'parent_id' => 0],
    ['id' => 6, 'name' => '笔记本', 'parent_id' => 5],
];

/**
 * 递归构建树形结构
 * @param array $list 平铺的结果集
 * @param int $parentId 当前查找的父节点ID
 * @return array 构建好的树形结构数组
 */
function buildTree(array $list, int $parentId = 0): array {
    $tree = [];
    foreach ($list as $item) {
        // 找到当前父ID对应的子节点
        if ($item['parent_id'] == $parentId) {
            // 递归查找该节点的子节点
            $children = buildTree($list, $item['id']);
            // 如果有子节点,就添加到当前节点的children字段
            if (!empty($children)) {
                $item['children'] = $children;
            }
            $tree[] = $item;
        }
    }
    return $tree;
}

// 调用函数生成树形结构
$treeResult = buildTree($categoryList);
// 打印结果查看结构
print_r($treeResult);
?>

实际数据库查询场景适配

实际开发中我们不会手动写死数据,而是先从数据库查询出结果再处理,以下示例结合PDO查询演示完整流程:

<?php
try {
    // 连接数据库,这里替换成你自己的数据库配置
    $pdo = new PDO('mysql:host=127.0.0.1;dbname=test;charset=utf8', 'root', '123456');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    // 查询所有分类数据,按需要排序
    $stmt = $pdo->query('SELECT id, name, parent_id FROM category ORDER BY id ASC');
    $categoryList = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    // 复用之前的buildTree函数
    function buildTree(array $list, int $parentId = 0): array {
        $tree = [];
        foreach ($list as $item) {
            if ($item['parent_id'] == $parentId) {
                $children = buildTree($list, $item['id']);
                if (!empty($children)) {
                    $item['children'] = $children;
                }
                $tree[] = $item;
            }
        }
        return $tree;
    }
    
    $treeResult = buildTree($categoryList);
    // 输出JSON格式方便接口返回
    echo json_encode($treeResult, JSON_UNESCAPED_UNICODE);
} catch (PDOException $e) {
    echo '数据库操作失败:' . $e->getMessage();
}
?>

递归使用的注意事项

使用递归处理数据库结果集时需要注意几个问题:

  • 如果层级过深可能导致递归栈溢出,一般业务场景下的分类层级不会超过10层,这种情况无需担心,如果层级特别深可以考虑迭代方式实现。
  • 每次递归都会遍历整个结果集,如果数据量特别大,可以先把结果集按parent_id分组,减少遍历次数,提升性能。
  • 如果数据库中可能出现循环引用(比如子节点的parent_id指向了自身的后代节点),需要在递归时增加已访问节点的判断,避免无限递归。

迭代方式替代方案

如果担心递归的性能或栈溢出问题,也可以用迭代的方式实现树形结构转换,以下是示例代码:

<?php
function buildTreeByIterate(array $list): array {
    $tree = [];
    $map = [];
    // 先把所有节点用id作为键存到map中
    foreach ($list as $item) {
        $map[$item['id']] = $item;
        $map[$item['id']]['children'] = [];
    }
    // 遍历map构建层级关系
    foreach ($map as $id => $item) {
        $parentId = $item['parent_id'];
        if ($parentId == 0) {
            // 顶层节点直接加入tree
            $tree[] = &$map[$id];
        } else {
            // 非顶层节点加入到对应父节点的children中
            if (isset($map[$parentId])) {
                $map[$parentId]['children'][] = &$map[$id];
            }
        }
    }
    return $tree;
}

// 测试迭代函数
$treeResult = buildTreeByIterate($categoryList);
print_r($treeResult);
?>

无论是递归还是迭代方式,核心都是理清父子节点的关联关系,根据实际业务场景选择合适的方法即可,递归写法更简洁易懂,迭代方式在大数据量或深层级场景下更稳定。

PHP递归数据库结果集多层数据结构修改时间:2026-06-02 23:38:20

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。