Laravel5.8 入口文件为public/index.php
创建了一个Kernel对象,调用handler处理请求,获取返回结果。将返回结果输出到客户端,处理terminate操作。
容器里绑定的是App\Http\Kernel,继承于Illuminate\Foundation\Http\Kernel。
Kernel中调用sendRequestThroughRouter方法,将请求传递到路由处理当中。
在sendRequestThroughRouter当中,在app中绑定了request实例,并解绑掉其他request实例对象。这样在程序其他地方都能通过app()->make('request')获取到request实例对象。
调用bootstrap方法,加载引导类。
创建一个Pipeline对象,将路由调度与中间件放入调用链当中。所有request先经过全局的中间件,然后在通过路由分发。
因为Piepline调用链都是一个个的回调方法,所以在dispatchToRouter返回了一个匿名回调函数。使用Kernel的route属性进行调度。
Kernel的route是一个Illuminate\Routing\Router对象。
从上面的方法可以看出,最终通过findRoute查找当前匹配的路由对象,并调用runRoute处理请求返回结果。
对路由的匹配,是通过routes这个路由Collections去匹配的。
先通过请求的方法获取当前方法下可用的路由集合,在从这些集合中去遍历获取第一个匹配的路由。集合中每个item是一个Illuminate\Routing\Router对象。因此最终判断路由与请求是否匹配调用的是Illuminate\Routing\Router中的matches方法。
在Illuminate\Routing\Router提供了四个默认的验证器,当四个验证器通过的时候才会匹配成功。四个验证器分别是UriValidator验证访问路径,MethodValidator验证请求方法,SchemeValidator验证访问协议,HostValidator验证域名。其中对uri的验证内部是使用正则表达式验证。
路由对请求的处理也是返回一个Pipeline,先将请求通过中间件,然后在执行路由的run方法。在run方法里面判断当前是执行控制器方法还是回调方法,根据不同类型分开执行。
通过当前路由的action配置判断是否是控制器或者回调方法。从代码中可以看到,其实就是我们路由配置中的第二个参数对应到action['user']。当我们第二参数是一个字符串的时候则认为是控制器方法,将请求转发到控制器里去处理。否则执行回调函数处理。
到这里,我们的请求就真的到达了我们的控制器的方法中,开始执行我们写的代码了。