Laravel 11.x 实现无限级分类伪静态路由需两步:一是在分类模型中添加并自动维护 slug_path 字段(如 electronics/phones/iphone),支持完整路径查询;二是在路由中用 Route::get('/category/{path}')->where('path', '.*') 捕获任意深度路径,控制器内直接 where('slug_path', $path) 一次查库,配合 Web 服务器正确转发请求至 public/index.php。

在 Laravel 11.x 中实现无限级分类的伪静态路由,核心是两件事:一是模型层支持递归关系与层级路径生成,二是路由层将动态层级(如 /category/electronics/phones/iphone)准确解析为对应分类,并交由控制器处理。这不是单纯套用 where('id', \d+) 就能解决的,必须结合 URL 路径解析与数据库查询逻辑。
分类模型需支持路径字段与递归查询
无限级分类若只靠 pid 和 level 字段,无法直接支撑伪静态路径匹配。推荐在数据表中增加一个 slug_path 字段(如 electronics/phones/iphone),用于存储从根到当前节点的完整路径标识。该字段应在创建或更新分类时自动维护。
- 迁移中添加:
$table->string('slug_path', 500)->unique()->index(); - 模型中定义访问器(可选):
public function getSlugPathAttribute() { return $this->attributes['slug_path'] ?? ''; } - 保存前自动构建(例如在模型的
saving事件或boot中):$parent = $this->getParent(); $this->slug_path = $parent ? $parent->slug_path . '/' . $this->slug : $this->slug;
注册通配符路由并捕获多段 slug
Laravel 11 不再默认启用 Route::fallback() 的宽松匹配,需显式使用正则约束或闭包路由来接收任意深度的路径段。推荐使用 whereAlphaNumeric 配合 .* 模式,但注意避免与其它路由冲突。
- 在
routes/web.php中添加:
use App\Http\Controllers\CategoryController;
Route::get('/category/{path}', [CategoryController::class, 'show'])
->where('path', '.*')
->name('category.show');
该写法允许匹配 /category/a、/category/a/b、/category/x/y/z 等任意层级路径,且不干扰其他以 /category 开头的固定路由(如 /category/create 应放在该路由之前)。
控制器中解析路径并查库
收到 {path} 后,不能直接按字符串分割后逐层查 ID——效率低且易出错。应一次性根据完整 slug_path 查询,确保路径存在且状态正常。
- 在
CategoryController@show中:
{
$category = Category::where('slug_path', $path)
->where('status', 1)
->with('parent', 'children')
->firstOrFail();
return view('categories.show', compact('category'));
}
这样既保证了 URL 语义清晰(如 /category/books/fiction/sci-fi),又避免了 N+1 查询或路径拼接错误。若需兼容旧版带 ID 的 URL(如 /category/123-electronics),可额外加一层正则判断,但非必需。
Nginx 或 Apache 必须正确转发请求
伪静态路由生效的前提是 Web 服务器把所有非物理文件的请求都交给 public/index.php。Laravel 11 默认已移除 .htaccess,Apache 用户需确认虚拟主机配置含 AllowOverride All 并启用 rewrite_module;Nginx 用户必须使用标准 try_files 规则:
try_files $uri $uri/ /index.php?$query_string;
}
特别注意:root 指向的是项目 public/ 目录,不是整个 Laravel 根目录。否则路径解析会失败,直接返回 404。



















