laravel路由逻辑

一,路由服务类

举例:Route::post('/form', 'Form@index'); 发生了什么

#Route详单于IlluminateSupportFacadesRoute,最后返回的是IlluminateRoutingRouter实例

#代理路由注册类RouteRegistrar的方法
__call($method, $parameters)
    {
        if (static::hasMacro($method)) {
            return $this->macroCall($method, $parameters);
        }

        return (new RouteRegistrar($this))->attribute($method, $parameters[0]);
    }

#IlluminateRoutingRouteRegistrar的魔术方法
__call($method, $parameters)
    {
        if (in_array($method, $this->passthru)) {
            return $this->registerRoute($method, ...$parameters);
        }

        if (in_array($method, $this->allowedAttributes)) {
            return $this->attribute($method, $parameters[0]);
        }
    }

#RouteRegistrar的attributes()方法,返回$this
$this->attributes[array_get($this->aliases, $key, $key)] = $value;

#RouteRegistrar的registerRoute()方法,返回$this
$this->router->{$method}($uri, $this->compileAction($action))

#RouteRegistrar的compileAction()方法,返回attributes和action
if (is_null($action)) {
            return $this->attributes;
        }
        if (is_string($action) || $action instanceof Closure) {
            $action = ['uses' => $action];
        }
        return array_merge($this->attributes, $action);

#Router的addRoute($methods, $uri, $action)方法
$this->routes->add($this->createRoute($methods, $uri, $action));

#RouteCollection的add(Route $route)方法,返回Route实例支持链式操作
$this->routes[$method][$domainAndUri] = $route;
$this->allRoutes[$method.$domainAndUri] = $route;
$this->nameList[$action['as']] = $route;
$this->actionList[trim($action['controller'], '\')] = $route;

二,注册路由

 路由文件api.php,web.php如何被加载

#AppProvidersRouteServiceProvider服务类继承自
IlluminateFoundationSupportProvidersRouteServiceProvider

#核心代码
public function map()
    {
        $this->mapApiRoutes();
        $this->mapWebRoutes();
    }

protected function mapWebRoutes()
    {
        Route::middleware('web')
             ->namespace($this->namespace)
             ->group(base_path('routes/web.php'));
    }

protected function mapApiRoutes()
    {
        Route::prefix('api')
             ->middleware('api')
             ->namespace($this->namespace)
             ->group(base_path('routes/api.php'));
    }

#router的
group(array $attributes, $routes)
    {
        $this->updateGroupStack($attributes);//修改$groupStack属性,因为Router是单例
        $this->loadRoutes($routes);
        array_pop($this->groupStack);//必须还原$groupStack属性
    }
#router的
loadRoutes($routes)
    {
        if ($routes instanceof Closure) {
            $routes($this);
        } else {
            $router = $this;
            require $routes;//加载路由文件的位置
        }
    }

三,查找匹配路由

如何从Request中找到匹配的路由

#Router的findRoute($request)方法
findRoute($request)
    {
        $this->current = $route = $this->routes->match($request);
        $this->container->instance(Route::class, $route);
        return $route;
    }

#RouteCollection的match(Request $request)方法
public function match(Request $request)
    {
        $routes = $this->get($request->getMethod());
        $route = $this->matchAgainstRoutes($routes, $request);
        if (! is_null($route)) {
            return $route->bind($request);
        }
        $others = $this->checkForAlternateVerbs($request);
        if (count($others) > 0) {
            return $this->getRouteForMethods($request, $others);
        }
        throw new NotFoundHttpException;
    }

#RouteCollection的matchAgainstRoutes(Request $request)方法
matchAgainstRoutes(array $routes, $request, $includingMethod = true)
    {
        return Arr::first($routes, function ($value) use ($request, $includingMethod) {
            return $value->matches($request, $includingMethod);
        });
    }

#Route的
matches();

compileRoute();
$this->compiled = (new RouteCompiler($this))->compile();
IlluminateRoutingRouteCompiler ->compile()
SymfonyComponentRoutingRoute ->compile()
SymfonyComponentRoutingRouteCompiler ::compile()
SymfonyComponentRoutingCompiledRoute对象 //最终的$this->compiled;

getValidators(); 
return static::$validators = [ 
    new UriValidator, #匹配path和where
    new MethodValidator, #匹配method(GET,POST...)
    new SchemeValidator, #匹配schema(http或者https)
    new HostValidator, #匹配host(hostname+port)
]; 
原文地址:https://www.cnblogs.com/tkzc2013/p/13816053.html