Laravel 之路由分发
前言
在阅读这篇文章之前,希望你阅读过了我之前写过的一系列的文章,但最起码阅读过这篇《Laravel 之路由匹配》,老人常说师傅领进门,修行靠个人,我也只能带大家整理思路,而忽略了一些细节,这是锻炼你自己的好机会。
代码分析
我们从Illuminate\Foundation\Http\Kernel
类开始进行分析,如果你不知道为什么,请阅读《Laravel 之路由匹配》。
当全局中间件运行完之后,就会调用dispatchToRouter
方法返回的回调:
这里的router
指的是Illuminate\Routing\Router
类的实例,我们看它的dispatch
方法:
方法dispatchToRoute
被调用:
在上一篇《Laravel 之路由匹配》中,我们已经讨论过了findRoute
了,我们本节的重点是runRoute
也就是路由分发。
runRoute
方法中,我们关心的重点是红色标出来的部分,我们直接分析runRouteWithinStack
方法:
第一部分,判断是否需要忽略路由中间件,这取决于我们是否向容器中注册了middleware.disable
,如果注册了并且为true的话,就会忽略我们设置的路由中间件。
我们分析需要路由中间件的情况,所以接下来调用gatherRouteMiddleware
方法:
这个方法的作用是收集匹配路由的中间件,进入到该函数中一探究竟,代码1(图中标出来的)调用Illuminate\Routing\Route
实例的gatherMiddleware
方法,在前面的文章中,我已经给大家解释过了,Laravel中每一条路由都是Illuminate\Routing\Route
类的对象。
这里首先调用middleware
方法,这个方法返回的值为我们注册路由的时候设置的中间价,比如通过以下方式:
controllerMiddleware
方法,这个方法很重要:
为了更能突出问题的重点,我会忽略掉一些很简单的方法调用,这里的isControllerAction
方法判断当前路由是否对应一个控制器,比如你可能有这样的路由'HomeController@index'
,那么这个路由对应的就是控制器,getController
方法返回当前路由的控制器类,getControllerMethod
返回控制器方法,在我们的例子中控制器和方法分别是HomeController
和index
。
我们再来分析controllerDispatcher
方法,从它的名字就可以看出它是控制器分发器,我们看下他的代码:
关于这个方法上面的代码,你可以假设不存在(实际上你确实可以这么做),继续分析,直接生成了Illuminate\Routing\ControllerDispatcher
类的对象,回到路由对象中controllerMiddleware
中,调用了Illuminate\Routing\ControllerDispatcher
类的getMiddleware
方法,我们来看这个方法:
这里判断控制器是否存在getMiddleware
方法,这个方法会返回一系列路由中间件,至于返回的格式,你可以查看Illuminate\Routing\ControllerDispatcher
类的methodExcludedByOptions
方法。
经过上面的分析,我们返回到Route
类的gatherMiddleware
方法,这个方法合并我们上面提到的中间件并返回,紧接着从Router
类的gatherRouteMiddleware
方法返回,继续返回到 runRouteWithinStack
方法中:
关于管道,我在之前的文章《老司机带你深入理解 Laravel 中间件(全局中间件)》中仔细讲过了,这里的管道操作运行所有的当前路由的中间件,中间件运行完之后,出发红色标出来的代码,也就是调用当前路由的run
方法,
1是运行控制器,2是运行回调方法,这里我们运行控制器,那么就会调用runController
方法:
Illuminate.outing.ontrollerDispatcher
类的dispatch
方法被调用:
第1部分解析控制器方法的依赖性,第2部分检查当前控制器是否存在callAction
,如果存在就调用它,当然一般的情况,代码3会直接被调用,比如对于上面的HomeController
来说,index
方法就被调用了。
总结
上面简要的给大家梳理了Laravel路由分发的过程,我忽略了一些不那么重要的内容,希望大家仔细去看,提醒大家一句,我分析的代码版本为5.8,所以请查看你的版本。学习需要坚持,才能成就非凡。学习交流群:
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: