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
相关产品推荐
相关产品推荐

