无限极分类

无限极分类

有个数组 $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年前 自动加精
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《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年前 评论

抱歉,我来是撑流量的: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年前 评论

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

5年前 评论

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

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年前 评论

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