无限极分类

无限极分类

有个数组 $arrs 类似于这样的结构

$arrs = [
    [
        'id'=>1,
        'parent_id'=>0
    ],
    [
        'id'=>2,
        'parent_id'=>1
    ],
    [
        'id'=>3,
        'parent_id'=>2
    ],
    [
        'id'=>4,
        'parent_id'=>0
    ],
    [
        'id'=>5,
        'parent_id'=>0
    ],
];

想要获得 id=1下的所有儿子,及儿子的儿子。

定义一个获取儿子的函数

function children($id,$arrs){
    $result =[];
    foreach ($arrs as $v){
        if($id==$v['parent_id']){
            $result[]=$v;
        }
    }
    return $result;
}

这个只能返回所有儿子,儿子的儿子获取不到

对上面的儿子在调用一次,就获取到儿子的儿子,在对儿子的儿子的儿子调用一次。。。

所以用到了递归的思想


function allChildren($id,$arrs){

    $result = [];
    $children = children($id,$arrs);//获取儿子数组
    foreach($children as $k=>$child){
        $result[$k]=$child;
        $childResult = allChildren($child['id'],$arrs);//获取儿子的儿子的儿子无穷尽也
        foreach ($childResult as $subChild) {
            $child['children'][]=$subChild;
            $result[$k] = $child;
        }
    }
    return $result;
}
print_r(allChildren(1,$arrs))
Array
(
    [0] => Array
        (
            [id] => 2
            [parent_id] => 1
            [children] => Array
                (
                    [0] => Array
                        (
                            [id] => 3
                            [parent_id] => 2
                        )

                )

        )

)

映射到数据库中可以实现上面的两个相对应的方法。

在laravel中就方便的多了,只需添加两个方法

//实现类似于children($id,$arrs)方法
 public function children(){
        return $this->hasMany(get_class($this),'parent_id');
    }
//实现了上面的allChildren($id,$arrs)方法
public function getAllChildren()
    {
        $result = [];
        $children = $this->children;

        foreach ($children as $child) {
            $result[] = $child;

            $childResult = $child->getAllChildren();
            foreach ($childResult as $subChild) {
                $result[] = $subChild;
            }
        }

        return $result;
    }

测试

Model::find(1)->getAllChildren();
本作品采用《CC 协议》,转载必须注明作者和本文链接
Make everything simple instead of making difficulties as simple as possible
本帖由系统于 5年前 自动加精
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 12
ALMAS

无须使用foreach遍历也可实现

    public function children() {
        return $this->hasMany(get_class($this), 'parent_id' );
    }

    public function allChildren() {
        return $this->children()->with( 'allChildren' );
    }
5年前 评论

抱歉,我来是撑流量的:https://segmentfault.com/a/119000001035909...
感觉我这样写会简单点。

5年前 评论
ALMAS

无须使用foreach遍历也可实现

    public function children() {
        return $this->hasMany(get_class($this), 'parent_id' );
    }

    public function allChildren() {
        return $this->children()->with( 'allChildren' );
    }
5年前 评论

抱歉,我来是撑流量的:https://segmentfault.com/a/119000001035909...
感觉我这样写会简单点。

5年前 评论

@ALMAS 其实应该说是无需自己手动去写循环,这样的写法确实是优雅多了

5年前 评论

会不会出现,无限循环啊?

5年前 评论
ThinkQ

不错

5年前 评论
Oraoto

为什么都叫无限,而不是无限 :joy:

5年前 评论
bestcyt

@sethhu 内容可以,但是写的太随意了吧....有不少误导的语句和错误

5年前 评论
bestcyt

根据一楼大佬整理的简单实践 博客:Laravel 无限级分类的简单实践
对待我酱紫的萌新菜鸟友好点0.0

5年前 评论
jcc123

@fanhaobai

Model::where('parent_id','=',null)->with('allChildren')->paginate($limit);
5年前 评论

可以做到平级显示吗?

4年前 评论

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