当前位置: 首页 > 后端技术 > PHP

Illuminate-routing注册路由源码分析

时间:2023-03-29 18:36:37 PHP

我们知道,在Laravel世界中,当外界传入一个Request时,会被Kernel处理,并返回给外界一个Response。当Kernel处理一个Request时,会调用illuminate/routing包提供的路由函数,根据当前Request转发相应的执行逻辑(执行逻辑的形式可以是Closure或Controller@Action)。同时,在进入执行逻辑前后,也会依次进入Middlewares的前处理和后处理。因此,一个Request被Kernel处理为Response的生命周期图如下:根据上面的流程,了解路由系统内部的工作原理是非常重要的!当然,它也很复杂。如果你想深入了解一个工具的用途,学习它的内部设计原理是画龙点睛之笔。在了解illuminate/routing是如何工作的之前,想象一下如何设计一个路由系统?让我们一起思考三分钟。注册路由:想想一个Request进入程序,携带的请求信息类似于GEThttps://localhost/api/v2/peop...,所以我们需要定义一个Route对象来表示这个信息,并在同时定义RouteCollection(CollectionofRoutes)来添加、获取和匹配一个Route。当程序启动时,开发者定义的所有路由(Route)列表都会被注册到RouteCollection中。查找路由:有了整个程序的路由列表,当一个Request进来的时候,可以根据当前Request的信息匹配到合适的Route,所以可以设计一个类似RouterManager的对象,起到统筹的作用开发经理Manager,调用$router->findRoute(\$request):Route匹配合适的Route。运行路由:现在已经匹配到对应的Route,可以调用RouterManager->runRoute($route):Response获取对应的Response返回给外界。因此,如果自己设计一个路由系统,可以按照上面三个步骤进行,思路很容易理解。其实Laravel的路由模块illuminate/routing也是按照这三个步骤设计的。本文将分析源码以及Laravel如何将开发者在routes/*.php中编写的路由列表注册到RouteCollection对象中。我们知道Laravel启动的第一步是实例化\Illuminate\Foundation\Application对象,而这个容器对象会调用\Illuminate\Routing\RoutingServiceProvider::register()到容器对象的$bindings数组属性中,key为-值形式注册,注册的对象主要有Router(也就是上面提到的RouterManager角色,可以类比为开发团队的开发经理角色)等。然后会默认调用\App\Providers\RouteServiceProvider::boot()方法加载routes/api.php和routes/web.php文件中注册的路由列表,Facade模式注册路由列表:Route::prefix($prefix)->middleware($middleware)->group('xxx/web.php');其实就是调用了\Illuminate\Routing\RouteRegistrar类中的attribute(key,value)方法来注册key-value形式的attributes数组属性。主要的group(string)方法调用Router::group()方法,然后调用loadRoutes(routes)执行routes/api.php和routes/web.php文件中定义的路由。对于每一个方法(如GET、POST等)的路由,在Router对象中都有相应的方法来为RouteCollection添加Route注册,比如常见的get(uri,action)方法,调用RouteCollection::add(route)方法将Route注册到RouteCollection中。要创建路由,请调用Router::createRoute(methods,uri,action)。由于$action可能是Closure也可能是Controller@Action,如果是Controller@Action的形式,就需要把字符串切割成数组,然后放到Route类的构造函数中。总结一下注册路由需要的对象:用Route表示路由信息,用RouteCollection表示路由集合列表,在RouteCollection中提供add和delete方法注册Route,而Router是概览的作用,注册路由是通过该对象发起,会调用RouteCollection注册路由,路由的元数据信息,如路由名称,由RouteRegistrar对象表示。从上面可以看出,在所有对象中,Router是画龙点睛的对象。通过以上分析,照明/路由路由系统的基本设计可以变得越来越清晰。一个Request进来后,Application首先根据上面的逻辑启动并注册路由列表,然后根据当前的Request信息查找对应的Route对象。那么如何根据当前的Request信息找到对应的Route呢?请参阅本系列的第二篇文章。