laravel后台控制器参数解析学习

  在配置laravel路由的时候,路由的url可能存在参数,它是如何被解析到控制器的呢。

  在Illuminate\Routing\Router类中的 dispath(Request $request) 方法,这个方法实际上就是路由匹配后执行的操作,即调用与路由匹配的某个控制器下的某个方法。它返回的是 $this->dispatchRoute($request) ,进入到这个方法。

 

  进入runRoute方法。

 

 

 

   返回值使用了管道,用于穿过中间件,最终在then中执行闭包返回响应,点击 $route->run() 。

 

  进入到 $this->runController() 中。

 

   $this->controllerDispatcher();//这里返回的是Illuminate\Routing\ControllerDispatcher对象 ,进入这个类的dispatch方法中

 

 

 

  这里找到了解析参数的方法, $this->resolveClassMethodDependencies($route->parametersWithoutNulls(),$controller,$method); 进入这个方法

 

 

 

  如果这个方法不存在,直接返回参数,$instance即为解析的控制器类名,进入到下面的方法

 

 

 

 

   开始解决依赖了,$parameters 即为url的请求参数,根据反射解析出该控制器需要的参数(只解析控制器所需的类,然后插入,其它Class参数不解析,url参数按控制器参数的排序来并非路由中定义的参数名)。控制器方法所需的参数也有可能是个对象,这样的参数是无法根据url参数解析的,而是通过内部的容器动态的创建这个对象,继续解析其它的参数,解析成功实例数加一($instance),并把解析的对应参数插入到对应位置,如果参数类型不是类,则不解析按默认的 $parameters 排序来,即url 的参数排序。

  如果设置的路由是

Route::get('/debug/args/{id}/{name}', 'Admin\DebugController@args');

  请求的url是 http://localhost/debug/args/2/DennisRitche 

  而控制器的参数顺序是

public function args(DubugFormRequest $request,$name,$id){

}

  那么根据框架的逻辑,解析到这些参数前,请求参数为

[
  0=>$request //DebugFormRequest的对象
  'id'=>"2",
  'name'=>"DennisRitche"         
]

 

  但是由于反射出来的参数顺序与请求参数并不一样,在解析完所有实例之后参数是这样的,之后回到之前的方法中 dispatch(Route $route,$controller,$method)//Illuminate\Routing\ControllerDispatcher对象中的方法 最终执行 $controller->{$method}(...array_values($parameters)); ,整个控制器的执行调用完成。而按照之前的解析顺序,原本的id成了name,name成了id。

   本文内容引用至老司机带你深入理解Laravel之验证器上(控制器参数解析)

posted on 2020-06-16 16:46  halt丶dodo  阅读(657)  评论(0编辑  收藏  举报

导航