Laravel 路由执行
代码展示
protected function runRouteWithinStack(Route $route, Request $request){ $shouldSkipMiddleware = $this->container->bound('middleware.disable') && $this->container->make('middleware.disable') === true; $middleware = $shouldSkipMiddleware ? [] : $this->gatherRouteMiddleware($route); return (new Pipeline($this->container)) ->send($request) ->through($middleware) ->then(function ($request) use ($route) { return $this->prepareResponse( $request, $route->run() ); });}public function run(){ $this->container = $this->container ?: new Container; try { // 控制器形式(Controller@Method) if ($this->isControllerAction()) { return $this->runController(); } // 匿名函数形式 return $this->runCallable(); } catch (HttpResponseException $e) { return $e->getResponse(); }}
控制器形式处理
protected function runController(){ return (new ControllerDispatcher($this->container))->dispatch( $this, $this->getController(), $this->getControllerMethod() );}public function getController(){ $class = $this->parseControllerCallback()[0]; if (! $this->controller) { $this->controller = $this->container->make($class); } return $this->controller;}protected function getControllerMethod(){ return $this->parseControllerCallback()[1];}protected function parseControllerCallback(){ return Str::parseCallback($this->action['uses']);}public static function parseCallback($callback, $default = null){ return static::contains($callback, '@') ? explode('@', $callback, 2) : [$callback, $default];}// Illuminate\Routing\ControllerDispatcherpublic function __construct(Container $container){ $this->container = $container;}public function dispatch(Route $route, $controller, $method){ // 控制器参数解析 $parameters = $this->resolveClassMethodDependencies( $route->parametersWithoutNulls(), $controller, $method ); if (method_exists($controller, 'callAction')) { return $controller->callAction($method, $parameters); } return $controller->{$method}(...array_values($parameters));}public function parametersWithoutNulls(){ // 返回过滤的从路径或主机名解析出来的对应的参数数组,类似 ['post'=>1,'comment'=>2] return array_filter($this->parameters(), function ($p) { return ! is_null($p); });}protected function resolveClassMethodDependencies(array $parameters, $instance, $method){ // __invoke 方式调用 if (! method_exists($instance, $method)) { return $parameters; } return $this->resolveMethodDependencies( $parameters, new ReflectionMethod($instance, $method) );}// 控制器的方法可以有自己的区别于路由参数的类类型参数,其他参数只能从路由获取public function resolveMethodDependencies(array $parameters, ReflectionFunctionAbstract $reflector){ $results = []; $instanceCount = 0; $values = array_values($parameters); foreach ($reflector->getParameters() as $key => $parameter) { // 类方法自己的类类型参数,尝试实例化 $instance = $this->transformDependency( $parameter, $parameters ); if (! is_null($instance)) { $instanceCount++; $results[] = $instance; } else { // 按照类方法的参数顺序依次存放数据 $results[] = isset($values[$key - $instanceCount]) ? $values[$key - $instanceCount] : $parameter->getDefaultValue(); } } return $results;}protected function transformDependency(ReflectionParameter $parameter, $parameters){ $class = $parameter->getClass(); // 类类型且没有实例化,则通过服务容器解决参数的依赖关系,并进行实例化 if ($class && ! $this->alreadyInParameters($class->name, $parameters)) { return $this->container->make($class->name); }}protected function alreadyInParameters($class, array $parameters){ return ! is_null(Arr::first($parameters, function ($value) use ($class) { return $value instanceof $class; }));}public function callAction($method, $parameters){ return call_user_func_array([$this, $method], $parameters);}
小结:
主要就是将路由获取到的参数依次对应到控制器方法的参数,当然控制器方法可以有自己的类类型参数匿名函数形式处理
protected function runCallable(){ $callable = $this->action['uses']; // 一样的处理方式 return $callable(...array_values($this->resolveMethodDependencies( $this->parametersWithoutNulls(), new ReflectionFunction($this->action['uses']) )));}
返回
即控制器的返回