You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel基于数据库构建无限级多级菜单:代码问题及优化求助

Laravel 多级菜单构建优化方案(支持无限级)

原代码存在的问题

  • 二级菜单赋值错误:原代码中$menu['subMenu'][$key]['subMenu'] = $subMenusTwoArr会覆盖之前的子菜单,且$subMenusTwoArr未正确追加子项,最终仅保留最后一个二级菜单。
  • N+1查询性能问题:每获取一级菜单就发起一次DB查询,层级越多查询次数越多,严重拖慢性能。
  • 硬编码层级限制:代码仅写死二级菜单逻辑,无法扩展到无限级菜单需求。

优化方案

1. 一次性获取所有菜单数据

通过单次DB查询拉取所有符合条件的菜单(含所有子层级),彻底解决N+1查询问题:

public function getMenu()
{
    // 一次性获取所有关联top_menu的菜单(含所有子层级)
    $allMenus = DB::table('menu as m')
        ->select('m.id', 'm.title', 'm.click_type', 'm.click_destination', 'm.ordering', 'm.parent_menu_id')
        ->join('menu_location as ml', 'm.id', '=', 'ml.menu_id')
        ->join('itemmeta as im', 'ml.item_meta_id', '=', 'im.id')
        ->where('m.site_id', 100)
        ->where('m.tenant_id', 10)
        ->where('im.slug', 'top_menu')
        ->where('im.is_enabled', 1)
        ->orderBy('m.parent_menu_id')
        ->orderBy('m.ordering')
        ->get()
        ->toArray();

    // 将菜单按parent_menu_id分组,方便快速查找子菜单
    $groupedMenus = collect($allMenus)->groupBy('parent_menu_id')->toArray();

    // 递归构建树形菜单,从parent_menu_id=0的根菜单开始
    return $this->buildMenuTree(0, $groupedMenus);
}

2. 递归构建无限级菜单树

编写递归函数,自动处理所有层级的子菜单,无需硬编码层级:

private function buildMenuTree($parentId, $groupedMenus)
{
    $menuTree = [];

    // 当前父ID无对应子菜单时,直接返回空数组
    if (!isset($groupedMenus[$parentId])) {
        return $menuTree;
    }

    // 遍历当前父ID下的所有子菜单
    foreach ($groupedMenus[$parentId] as $menuItem) {
        $menu = [
            'id' => $menuItem->id,
            'title' => $menuItem->title,
            'click_type' => $menuItem->click_type,
            'click_destination' => $menuItem->click_destination,
            'ordering' => $menuItem->ordering
        ];

        // 递归获取当前菜单的子菜单
        $childMenus = $this->buildMenuTree($menuItem->id, $groupedMenus);
        if (!empty($childMenus)) {
            $menu['subMenu'] = $childMenus;
        }

        $menuTree[] = $menu;
    }

    return $menuTree;
}

代码核心优势

  • 性能优化:仅发起1次DB查询,避免多次查询带来的性能损耗。
  • 无限级支持:递归函数自动适配所有层级的子菜单,无需修改代码即可扩展菜单深度。
  • 有序展示:查询时通过orderBy保证菜单按父ID和自定义排序规则展示。
  • 易维护:逻辑集中,后续修改菜单字段或筛选条件只需调整一处代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 11:21:06