Laravel 6.2 动态调用控制器操作的自定义路由代码咨询
这段Laravel动态路由的功能与运行逻辑
核心功能
这是一套用来减少重复路由编写的通用动态路由规则,不用为每个控制器、每个方法单独写路由条目,靠URL路径就能自动匹配执行对应的控制器逻辑,所有走这条路由的请求都会先经过supadminauth超级管理员权限校验中间件,基本都是后台管理系统为了省事儿搞的快速路由写法。
逐段运行逻辑拆解
1. 路由匹配规则定义
Route::match(['get', 'post'], '{controller}/{action?}/{params1?}/{params2?}', function ($controller, $action = 'index', $params1 = '',$params2 = '') {
- 同时兼容GET、POST两种请求方法,不限制请求类型的场景都可以命中该规则
- 路径规则定义了4段占位符,带
?标记的为非必填项:- 第一段
{controller}:对应URL的第一段路径,用来匹配要调用的控制器 - 第二段
{action?}:对应URL的第二段路径,用来匹配控制器里要执行的方法名,不传时默认执行控制器的index方法 - 第三、第四段
{params1?}/{params2?}:用来给控制器方法传递业务参数
- 第一段
- 闭包函数会自动接收4个占位符传递的参数,同时给了默认值,避免路径段缺失时报参数错误。
2. 控制器解析与业务逻辑调度
$params = explode('/', $params1); $params[1] = $params2; $app = app(); $controller = $app->make("\App\Http\Controllers\" . ucwords($controller) . 'Controller'); return $controller->callAction($action, $params);
- 先执行
explode拆分$params1,实际这步作用不大——因为Laravel的路由占位符本身不会匹配斜杠,拆分出来基本就是单元素数组;后续把$params2赋值给数组索引1的位置,是为了凑出一个按顺序排列的参数列表,后续会按顺序传给目标控制器的方法 - 通过
app()获取Laravel服务容器实例,用容器的make()方法解析控制器实例而非手动new,可以自动解析控制器构造函数中依赖的服务,不会破坏Laravel的依赖注入能力 - 拼接完整的控制器命名空间:把URL传入的控制器名首字母转大写后,加上
App\Http\Controllers\的命名空间前缀、Controller类后缀,比如URL传入user,最终会解析到App\Http\Controllers\UserController类 - 调用Laravel控制器基类自带的
callAction方法,执行对应控制器中的目标方法,同时把组装好的参数列表传入,自动完成控制器逻辑的执行与响应返回。
3. 权限中间件绑定
})->middleware('supadminauth');
- 给所有命中该动态路由的请求统一绑定
supadminauth中间件,通常这个中间件的作用是校验当前请求是否为已登录的超级管理员,未通过校验的请求会被直接拦截。
实际使用的注意坑点
- 这条是通配路由,必须放在web.php路由文件的最末尾,不然会覆盖前面定义的明确路由规则——比如你前面提前定义了登录页路由
/login,要是这个动态路由在它前面,访问/login就会被解析成找LoginController的index方法,直接逻辑错乱 - 当前规则最多仅支持给控制器方法传递2个业务参数,需要更多参数时要自行扩展路径占位符
- 原代码用的
ucwords字符串处理有局限,比如你的控制器是AdminUserController这种多段驼峰命名的,传入adminuser过去,ucwords只能转成Adminuser,根本匹配不到正确的类,需要自行调整字符串处理逻辑才能适配。
内容的提问来源于stack exchange,提问作者Skumar
相关产品推荐
相关产品推荐

