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

Laravel 5.6嵌套分类查询:按名称获取所有子分类

获取指定分类的所有层级子分类(Laravel 5.6)

针对你的需求,我整理了两种实用的实现方式,都能帮你传入分类名称后获取它所有层级的子分类(不管深度):

方法一:利用Eloquent递归关系

这种方式基于Laravel的模型关联,代码更面向对象,返回的是模型实例,方便后续业务操作。

首先,确保你有Category模型,定义递归关联:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    protected $table = 'categories';

    // 定义直接子分类的关联
    public function children()
    {
        return $this->hasMany(self::class, 'cat_parent_id', 'id');
    }

    // 递归获取所有层级的后代分类
    public function allChildren()
    {
        return $this->children()->with('allChildren');
    }
}

然后在控制器或服务类中编写获取方法:

use App\Category;
use Illuminate\Support\Collection;

public function getAllSubcategories(string $categoryName): Collection
{
    // 先根据名称找到目标父分类
    $parentCategory = Category::where('name', $categoryName)->first();

    if (!$parentCategory) {
        // 分类不存在时返回空集合,你也可以根据业务抛出异常
        return collect();
    }

    // 获取嵌套结构的所有子分类
    $nestedSubcategories = $parentCategory->allChildren;

    // 如果需要扁平化的子分类集合(去掉嵌套层级),使用flatten()
    $flattenedSubcategories = $nestedSubcategories->flatten();

    return $flattenedSubcategories;
}

方法二:使用递归CTE(数据库层面查询)

这种方式直接在数据库层用递归查询实现,性能更优,适合分类数据量较大、层级较深的场景。

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Collection;

public function getAllSubcategories(string $categoryName): Collection
{
    // 获取目标分类的ID
    $parentId = Category::where('name', $categoryName)->value('id');

    if (!$parentId) {
        return collect();
    }

    // 递归CTE查询所有层级子分类
    $subcategories = DB::table('categories')
        ->withRecursive(['subcategories' => function ($query) use ($parentId) {
            // 初始查询:获取目标分类的直接子分类
            $query->select('id', 'name', 'cat_parent_id')
                ->from('categories')
                ->where('cat_parent_id', $parentId)
                ->unionAll(function ($query) {
                    // 递归查询:获取子分类的子分类,以此类推
                    $query->select('c.id', 'c.name', 'c.cat_parent_id')
                        ->from('categories as c')
                        ->join('subcategories as sc', 'sc.id', '=', 'c.cat_parent_id');
                });
        }])
        ->select('id', 'name', 'cat_parent_id')
        ->from('subcategories')
        ->get();

    return $subcategories;
}

两种方法的区别

  • Eloquent关联法:返回模型实例集合,支持调用模型的方法和关联,代码更优雅,但层级极深时可能有轻微性能损耗。
  • CTE查询法:返回的是StdClass对象集合,查询效率更高,适合大数据量场景,但无法直接使用模型的方法。

内容的提问来源于stack exchange,提问作者Rakesh kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:24:39