laravel路由逻辑
一,路由服务类
举例:Route::post('/form', 'Form@index'); 发生了什么
#Route详单于\Illuminate\Support\Facades\Route,最后返回的是Illuminate\Routing\Router实例 #代理路由注册类RouteRegistrar的方法 __call($method, $parameters) { if (static::hasMacro($method)) { return $this->macroCall($method, $parameters); } return (new RouteRegistrar($this))->attribute($method, $parameters[0]); } #Illuminate\Routing\RouteRegistrar的魔术方法 __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如何被加载
#App\Providers\RouteServiceProvider服务类继承自 Illuminate\Foundation\Support\Providers\RouteServiceProvider #核心代码 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(); Illuminate\Routing\RouteCompiler ->compile() Symfony\Component\Routing\Route ->compile() Symfony\Component\Routing\RouteCompiler ::compile() Symfony\Component\Routing\CompiledRoute对象 //最终的$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) ];
分类:
php_adv
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?