分享一个用 ORM 写无限极分类的帖子, 大佬请跳过.

实现无限极分类,运用场景为:树目录/部门分类/动态菜单等

直接上代码:
模型:

 protected $table = 'menu';//自定义表名(protected $table)
    protected $primaryKey = 'id';//主键字段,默认为id
    public $timestamps = false;//如果数据表中没有created_at和updated_id字段,则$timestamps则可以不设置,默认为true

    public function childrenModule()
    {
        return $this->hasMany(Menu::class,'fatherId','id');
    }

    public function children()
    {
        return $this->childrenModule()->with('children');
    }

控制层:

  $data = Menu::where(['fatherId' => 0, 'isDel' => 0])
            ->select('id', 'title', 'href', 'fontFamily', 'icon', 'spread', 'isCheck')
            ->with(['children:id,fatherId,title,href,fontFamily,icon,spread'])
            ->get();

最终实现效果:

{
    "id": 10,
    "title": "框架管理",
    "href": "sys/pages/frame/index",
    "fontFamily": "ok-icon",
    "icon": "",
    "spread": 0,
    "isCheck": 0,
    "children": [
        {
            "id": 11,
            "fatherId": 10,
            "title": "路由管理",
            "href": "",
            "fontFamily": "ok-icon",
            "icon": "&#xe6a3",
            "spread": 0,
            "children": [
                {
                    "id": 12,
                    "fatherId": 11,
                    "title": "路由管理1",
                    "href": null,
                    "fontFamily": "ok-icon",
                    "icon": "&#xe6a3",
                    "spread": 0,
                    "isCheck": 0,
                    "isDel": 1,
                    "children": []
                },
                {
                    "id": 13,
                    "fatherId": 11,
                    "title": "路由管理2",
                    "href": null,
                    "fontFamily": "ok-icon",
                    "icon": "&#xe6a3",
                    "spread": 0,
                    "isCheck": 0,
                    "isDel": 1,
                    "children": []
                }
            ]
        }
    ]
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 7

不得不说,,laravel真的是非常优雅

4年前 评论

有一层就多查询一次

4年前 评论
ct4477xx_join (楼主) 4年前
winter-ice (作者) 4年前
ct4477xx_join (楼主) 4年前
largezhou 4年前

如果menu表数据不多,用DB全部查询出来 存入数组

再用数组来排序父子关系

https://github.com/lyxxg/lartree
我之前也写过一个包,后面发现没啥用,需求不一致。
总是在此基础上修改。

4年前 评论

分类的话可以看看预排序这个kalnoy/nestedset

4年前 评论

@ct4477xx_join

左右值算法:https://github.com/lazychaser/laravel-nest...

另一种算法:https://github.com/jiaxincui/closure-table

集合直接转无限级:https://github.com/TypiCMS/NestableCollect...

前两种适合量大点的,都需要动数据库,第三种不需要动数据库,适合菜单啥的这种

4年前 评论
ct4477xx_join (楼主) 4年前

直接给代码 我喜欢这样搞

$data = self::query()->orderBy('sort','asc')->get()->toArray();
        $items = [];
        foreach ($data as $value) {
            $items[$value['id']] = $value;
        }
        $tree = [];
        foreach ($items as $k => $v) {
            if (isset($items[$v['pid']])) {
                $items[$v['pid']]['children'][] = &$items[$k];
            } else {
                $tree[] = &$items[$k];
            }

        }
        return $tree;

这样查一次就好 后面重组的时间也是O(n)

4年前 评论
ct4477xx_join (楼主) 4年前

都是大佬,,,,活到老 学到老...

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!