创建多级菜单 php Laravel

Create Multi level menu php Laravel

我正在 laravel 中执行创建动态菜单的功能,并且我有 tbl_menu table 如下:

menu_id   parent_id  menu_name      link       order   
  1           0       Level_1       url_1        1  
  2           0       Level_1       url_2        1
  3           2       Level_2       url_3        2
  4           2       Level_2       url_4        3 
  5           4       Level_3       url_5        3 

我希望结果是一个如下所示的数组:

-Level_1
        -Level_2
        -Level_2
-Level_1
       _Level_2
       _Level_2
               _Level_3

我的代码如下:

public function SelectAllChildeLv1ByParentId($id){
    $result = DB::table('tbl_menu')->where('parent_id', $id)
            ->orderBy('order', 'asc')->get();
    return $result;
}

public function SelectAllMenuParent(){
        $result = DB::table('tbl_menu')->where('parent_id', 0)
            ->orderBy('order', 'asc')->get();
        return $result;
    }
public function getMenuChildren($listParent, $step = 3)
    {
        $results = [];

        if ($step > 0) {
            $step--;
            if($listParent) {
                foreach($listParent as $index => $parent) {
                    $listChild = $this->SelectAllChildeLv1ByParentId($parent->menu_id);
                    $listChild1 = $this->getMenuChildren($listChild, $step);
                    $results[$index] = $parent;
                    $results[$index]->menu_child = $listChild1;
                }
            }
        }

        return $results;
    }

public function getAllMenus() {
        $allMenuParent = $this->SelectAllMenuParent();
        $results = $this->getMenuChildren($allMenuParent);
        return $results;
    }

结果正确,但 运行 查询太多。我想优化它,但还没有弄清楚。 感谢您的帮助。

尝试:

public function get()
{
  $menu = DB::table('tbl_menu')
  ->orderBy('order', 'asc')->get();
  $parents = $menu->where('parent', 0);
  $items = self::tree($parents, $menu);
  return $items;
}

public function tree($items, $all_items)
{
  $data_arr = array();
  foreach ($items as $i => $item) {
    $data_arr[$i] = $item->toArray(); //all column attributes
    $find = $all_items->where('parent', $item->id);
    //$data_arr[$i]['tree'] = array(); empty array or remove if you dont need it
    if ($find->count()) {
      $data_arr[$i]['tree'] = self::tree($find, $all_items);
    }
  }

  return $data_arr;
}

使用eloquent.

首先,将此添加到 'tbl_menu' 模型中:

protected $with = ['children'];

public function children()
{
    return $this->hasMany(YOUR_CLASS_NAME::class, 'parent_id', 'id')->orderBy('order');
}

现在如果调用主菜单,所有子项。

等:YOUR_CLASS_NAME::where('parent_id', 0)->get().

那么调用的时候就可以使用递归了

public $menus = [];
public $level = 0;

public function getMenus($request){
    $menus = YOUR_CLASS_NAME::where('parent_id', 0)
        ->orderBy('order')
        ->get();

    $this->recursiveMenu($menus);

    return $this->menus;
}

public function recursiveMenu($menus, $lvl = 0){
    foreach ($menus as $key => $menu) {
        $this->menus[$menu->id] = str_repeat('—', $lvl).' '.$menu->title;

        if($menu->children){
            $this->level++;
            $this->recursiveMenu($menu->children, $this->level);
        }
        if (!isset($menu[$key+1])) {
            $this->level--;
        }
    }
}