推荐使用 laravel-nestedset 扩展包实现 Laravel 9.x 无限级分类,基于 MPTT 算法,支持自动维护 lft/rgt、节点增删改查、树结构修复等完整功能。

在 Laravel 9.x 中使用 nestedset 实现无限级分类,推荐使用 laravel-nestedset 这个成熟、稳定且文档清晰的扩展包。它基于 Modified Preorder Tree Traversal(MPTT)算法,性能好、API 简洁,天然支持无限层级、移动节点、获取子树/祖先等常见需求。
安装与基础配置
执行以下命令安装包(Laravel 9 兼容 v6.x 版本):
composer require kalnoy/nestedset
无需发布配置或服务提供者(Laravel 5.5+ 自动发现),但需为模型添加迁移字段:
- 在分类表(如
categories)的迁移中添加三个必需字段:
$table->integer('lft')->unsigned()->index();<br>$table->integer('rgt')->unsigned()-gt;index();<br>$table->integer('depth')->unsigned()->default(0);
运行 php artisan migrate 后,在对应模型(如 App\Models\Category)中引入 trait 并声明使用:
use Kalnoy\Nestedset\Node;<br><br>class Category extends Model<br>{<br> use Node;<br>}
创建与插入节点(支持任意层级)
插入根节点或子节点都只需调用链式方法,无需手动计算 lft/rgt:
- 添加根节点:
Category::create(['name' => '电子产品']); - 添加子节点(指定父级):
$parent->children()->create(['name' => '手机']); - 追加到同级末尾:
$sibling->appendNode(['name' => '平板']); - 插入到某节点前/后:
$node->beforeNode(['name' => '耳机']);或$node->afterNode(['name' => '配件']);
所有操作自动维护树结构,无需额外处理。
查询常用关系数据
利用内置作用域和方法快速获取结构化数据:
- 获取全部根节点:
Category::roots()->get(); - 获取某节点的所有后代(含自身):
$node->descendantsAndSelf()->toTree(); - 获取完整路径(祖先链):
$node->ancestors->push($node); - 获取直接子节点(不递归):
$node->children; - 判断是否为叶子节点:
$node->isLeaf();
若需前端渲染树形菜单,推荐用 toTree() 方法返回嵌套集合,再配合 Blade 递归组件或 @each 渲染。
更新与删除的安全操作
删除节点会自动移除其整个子树(级联),但可先断开关联避免误删:
- 安全删除(保留子节点为根):
$node->deleteAndShiftUp(); - 彻底删除(含子孙):
$node->delete(); - 移动节点到新父级:
$node->moveAfter($newParent);或$node->makeRoot(); - 修复异常树结构(开发调试用):
Category::fixTree();
建议在关键操作前后用 Category::isBroken() 检查树完整性,尤其在批量导入或手动修改数据后。
不复杂但容易忽略:确保数据库字段类型为 unsignedInteger(非 bigInteger),否则大站点可能因 lft/rgt 超出范围报错;另外,所有写操作默认开启事务,无需额外包裹。











