最近在看laravel的源码,下面的就当是个笔记,会记录一下从代码的第一行到结束都经历了什么。
- Illuminate\Routing\Router.php下findRoute()做了什么
protected function findRoute($request)
{
$this->current = $route = $this->routes->match($request);
$this->container->instance(Route::class, $route);
return $route;
}
这个方法里通过传入的request请求,返回当前的一个route实例,主要通过当前url,返回当前用的是哪个controller,或者是个function。那么它又是如何把request和路由对应起来的呢?
回答这个问题先要看上面的match方法是如何运行的,调用的是Illuminate\Routing\RouteCollection中的match方法。
public function match(Request $request)
{
$routes = $this->get($request->getMethod());//这里能获取所有的uri
$route = $this->matchAgainstRoutes($routes, $request);//通过所有链接与当前的url进行匹配
}
public function get($method = null)
{
return is_null($method) ? $this->getRoutes() : Arr::get($this->routes, $method, []);//$this->routes所有的路由
}
在这个小节里主要看是怎么往$this->routes赋值的
那么这其中的过程是怎么样的呢?其实在项目的启动时候会加载routes下的文件,比如web.php,可以参考这篇文章,在这里说明了web.php是如何加载的。在这个文件中
Route::get('/rose', function () {
return view('welcome');
});
运行了Route::get()方法,其实没有这个静态方法,而是运行了Illuminate\Routing\Router中的get方法,可以参考这篇文章
//Illuminate\Routing\Router
public function __construct(Dispatcher $events, Container $container = null)
{
$this->events = $events;
$this->routes = new RouteCollection;
$this->container = $container ?: new Container;
}
public function get($uri, $action = null)
{
return $this->addRoute(['GET', 'HEAD'], $uri, $action);
}
public function addRoute($methods, $uri, $action)
{
return $this->routes->add($this->createRoute($methods, $uri, $action));//上面实例的类是RouteCollection
}
//Illuminate\Routing\RouteCollection
public function add(Route $route)
{
$this->addToCollections($route);
$this->addLookups($route);
return $route;
}
protected function addToCollections($route)
{
$domainAndUri = $route->getDomain().$route->uri();
foreach ($route->methods() as $method) {
$this->routes[$method][$domainAndUri] = $route;//在这里保存了所有的路由 !!!!!!!!!!!!!!!!!
}
$this->allRoutes[$method.$domainAndUri] = $route;
}
这里因为加载了每个路由文件,所以能收集到所有的uri,把它们放到$this->routes中去,也就解决了上面的疑问。
未完待续...