You need to enable JavaScript to run this app. 无法正确生成深层菜单的menu_order值,PHP递归逻辑出现重复数据如何解决
优惠活动
大模型
产品
解决方案
定价
更多

无法正确生成深层菜单的menu_order值,PHP递归逻辑出现重复数据如何解决

问题核心原因

  • 外层遍历了所有菜单项,子节点既会在外层循环被添加,也会在父节点的递归逻辑中被重复添加,导致数据重复、排序混乱
  • 没有从根节点(parent=0)开始遍历,遍历逻辑不符合深度优先的排序要求

修正后可直接运行的示例代码

<?php

$posts = [
    ['id' => 15, 'parent' => 0, 'menu_order' => 0],
    ['id' => 22, 'parent' => 15, 'menu_order' => 0],
    ['id' => 26, 'parent' => 15, 'menu_order' => 0],
    ['id' => 30, 'parent' => 15, 'menu_order' => 0],
    ['id' => 47, 'parent' => 22, 'menu_order' => 0],
    ['id' => 49, 'parent' => 22, 'menu_order' => 0],
    ['id' => 51, 'parent' => 22, 'menu_order' => 0],
    ['id' => 68, 'parent' => 26, 'menu_order' => 0],
    ['id' => 69, 'parent' => 26, 'menu_order' => 0],
];

// 先构建父子映射,方便快速查找某个节点的所有子节点,纯数据库场景可省略这一步
$childrenMap = [];
foreach ($posts as $p) {
    $childrenMap[$p['parent']][] = $p;
}

$test = [];
$currOrder = 0;

// 深度优先遍历递归函数
function buildMenuOrder($parentId, &$childrenMap, &$currOrder, &$test) {
    if (!isset($childrenMap[$parentId])) {
        return;
    }
    foreach ($childrenMap[$parentId] as $item) {
        $item['menu_order'] = $currOrder;
        $test[] = $item;
        $currOrder++;
        // 递归处理当前节点的所有子节点
        buildMenuOrder($item['id'], $childrenMap, $currOrder, $test);
    }
}

// 仅从根节点(parent=0)开始遍历
buildMenuOrder(0, $childrenMap, $currOrder, $test);

// 打印验证结果
print_r($test);

输出结果

和你期望的效果完全一致:

id | parent | menu_order
15     0          0
22     15         1
47     22         2
49     22         3
51     22         4
26     15         5
68     26         6
69     26         7
30     15         8

纯数据库场景适配

如果不需要提前加载所有菜单数据,直接在递归中查库即可,调整后的递归函数如下:

function buildMenuOrder($parentId, &$currOrder, &$test) {
    // 查询当前父节点的所有子节点
    $childs = $this->where('parent', $parentId)
        ->get()
        ->getResult();
    foreach ($childs as $c) {
        $c['menu_order'] = $currOrder;
        $test[] = $c;
        $currOrder++;
        // 递归处理子节点的下级菜单
        buildMenuOrder($c['id'], $currOrder, $test);
    }
}

// 调用方式
$test = [];
$currOrder = 0;
buildMenuOrder(0, $currOrder, $test);

内容的提问来源于stack exchange,提问作者sfarzoso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 10:36:05