摘要:配置項即時載入的服務提供者根目錄所有即時載入的服務注冊完成之后,會立即調用方法,并標記為已載入。最終就是將數組設置給的屬性將運用到所有的路由,再加載。
Laravel 配置項即時載入的服務提供者 (根目錄:/var/www/laravel/)
所有即時載入的服務注冊完成之后,會立即調用 register 方法,并標記為已載入。 隨后通過 IlluminateFoundationBootstrapBootProviders 啟動項來調用所有的即時加載服務提供者的 boot 方法 查看根據 config/app.php 中的 providers 生成的 bootstrap/cache/services.php "eager" => array ( // 系統服務提供者 0 => "IlluminateAuthAuthServiceProvider", // 注入驗證相關對象 1 => "IlluminateCookieCookieServiceProvider", // 注入cookie對象 2 => "IlluminateDatabaseDatabaseServiceProvider", // 注入db相關對象 3 => "IlluminateEncryptionEncryptionServiceProvider", // 注入加解密對象 4 => "IlluminateFilesystemFilesystemServiceProvider", // 注入文件相關對象 5 => "IlluminateFoundationProvidersFoundationServiceProvider",// 注入基礎的請求對象 6 => "IlluminateNotificationsNotificationServiceProvider", // 注入通知對象 7 => "IlluminatePaginationPaginationServiceProvider", // 注入分頁相關對象 8 => "IlluminateSessionSessionServiceProvider", // 注入session相關對象 9 => "IlluminateViewViewServiceProvider", // 注入視圖相關對象 10 => "LaravelPassportPassportServiceProvider", // 注入passport相關對象 // 配置項服務提供者 11 => "AppProvidersAppServiceProvider", 12 => "AppProvidersAuthServiceProvider", 13 => "AppProvidersEventServiceProvider", 14 => "AppProvidersRouteServiceProvider", )路由相關服務提供者
// 主要是注冊完之后的 boot 方法調用 AppProvidersRouteServiceProvider public function boot() { // 可以加入自己的操作 parent::boot(); } public function boot() { $this->setRootControllerNamespace(); // 若執行了 php artisan routes:cache(自動生成路由緩存文件,注意:建議只在項目上線時操作),直接加載 if ($this->app->routesAreCached()) { $this->loadCachedRoutes(); } else { // 加載路由 $this->loadRoutes(); // 設置系統啟動時的事件監聽函數 $this->app->booted(function () { $this->app["router"]->getRoutes()->refreshNameLookups(); }); } } protected function setRootControllerNamespace() { if (! is_null($this->namespace)) { // 設置 $this->instances["url"] (IlluminateRoutingUrlGenerator對象)的 rootNamespace 屬性 $this->app[UrlGenerator::class]->setRootControllerNamespace($this->namespace); } } public function routesAreCached() { return $this["files"]->exists($this->getCachedRoutesPath()); } public function getCachedRoutesPath() { return $this->bootstrapPath()."/cache/routes.php"; } protected function loadRoutes() { if (method_exists($this, "map")) { $this->app->call([$this, "map"]); } } public function map() { $this->mapApiRoutes(); $this->mapWebRoutes(); } // API 相關的路由 protected function mapApiRoutes() { Route::prefix("api") ->middleware("api") ->namespace($this->namespace) ->group(base_path("routes/api.php")); } // WEB 相關的路由 protected function mapWebRoutes() { Route::middleware("web") ->namespace($this->namespace) ->group(base_path("routes/web.php")); } public function booted($callback) { $this->bootedCallbacks[] = $callback; // 如果應用已經啟動了,則直接調用 if ($this->isBooted()) { $this->fireAppCallbacks([$callback]); } } // Route 是 Facde 的調用方式 分析: Route::middleware("web") ->namespace($this->namespace) ->group(base_path("routes/web.php")); Route::middleware public static function __callStatic($method, $args) { // 獲取應用的 router 對象 $instance = static::getFacadeRoot(); if (! $instance) { throw new RuntimeException("A facade root has not been set."); } // 將 Router::middleware() 轉化為應用的 Router->middleware() 方式,若 Router 沒有 middleware 方法,則直接觸發 __call return $instance->$method(...$args); } public function __call($method, $parameters) { if (static::hasMacro($method)) { return $this->macroCall($method, $parameters); } // 將不存在的方法的調用委托給 RouteRegistrar 處理, return (new RouteRegistrar($this))->attribute($method, $parameters[0]); } public function attribute($key, $value) { // 只允許指定的屬性設置($allowedAttributes = ["as", "domain", "middleware", "name", "namespace", "prefix",]) if (! in_array($key, $this->allowedAttributes)) { throw new InvalidArgumentException("Attribute [{$key}] does not exist."); } // 支持.方式來存放屬性 $this->attributes[array_get($this->aliases, $key, $key)] = $value; return $this; } public function group($callback) { $this->router->group($this->attributes, $callback); } public function group(array $attributes, $routes) { $this->updateGroupStack($attributes); $this->loadRoutes($routes); array_pop($this->groupStack); } protected function loadRoutes($routes) { if ($routes instanceof Closure) { $routes($this); } else { $router = $this; require $routes; } }
小結
Route::middleware("web") ->namespace($this->namespace) ->group(base_path("routes/web.php")); 實際就是將 middleware namespace 加入到 RouteRegistrar 對象里面的 attributes 數組屬性,并返回 RouteRegistrar 對象,再調用 RouteRegistrar 對象的 group 方法,也就是調用 router 對象的 group 方法。最終就是將["middleware" => "web", "namespace" => $this->namespace] 數組設置給 $this->router 的groupStack 屬性(將運用到所有的路由),再加載 config/web.php。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/22626.html
摘要:為了一探究竟,于是開啟了這次應用性能調優之旅。使用即時編譯器和都能輕輕松松的讓你的應用程序在不用做任何修改的情況下,直接提高或者更高的性能。 這是一份事后的總結。在經歷了調優過程踩的很多坑之后,我們最終完善并實施了初步的性能測試方案,通過真實的測試數據歸納出了 Laravel 開發過程中的一些實踐技巧。 0x00 源起 最近有同事反饋 Laravel 寫的應用程序響應有點慢、20幾個并...
摘要:實例化各服務提供者,根據其屬性將服務進行分類延遲服務即時服務,從而得到一個數組格式如,延遲處理注冊延遲的服務,以后再進行調用注冊延遲的事件即時處理直接進行注冊調用等,并重新寫入到,然后根據此文件進行相應的處理。 Laravel Kernel引導流程分析 代碼展示 protected function sendRequestThroughRouter($request) { # ...
摘要:問題分析通過閱讀源碼發現,中的服務都是按需綁定并加載。在服務按需綁定并加載的時候,使用了類似組件的形式通過載入配置項并綁定服務。因為在這個時候的相關配置文件還沒有被載入。 問題描述 公司一個高并發API需要從Laravel移植到Lumen,由于數據庫配置信息是通過遠程或者緩存讀取后動態配置,所以在中間件時使用到了 Config::set 然而實際運行時發現數據庫配置并沒有更新。 由于是...
摘要:使用即時編譯器和都能輕輕松松的讓你的應用程序在不用做任何修改的情況下,直接提高或者更高的性能,之前做個一個實驗,具體請見使用提升程序性能。 本文經授權轉自 PHPHub 社區 說明 性能一直是 Laravel 框架為人詬病的一個點,所以調優 Laravel 程序算是一個必學的技能。 接下來分享一些開發的最佳實踐,還有調優技巧,大家有別的建議也歡迎留言討論。 這里是簡單的列表: 配置信...
摘要:今天,讓我們深入研究下的廣播系統。廣播系統的目的是用于實現當服務端完成某種特定功能后向客戶端推送消息的功能。這種使用場景可以完美詮釋廣播系統的工作原理。另外,本教程將使用廣播系統實現這樣一個即時通信應用。 這是一篇譯文,譯文首發于 Laravel 廣播系統工作原理,轉載請注明出處。 今天,讓我們深入研究下 Laravel 的廣播系統。廣播系統的目的是用于實現當服務端完成某種特定功能后向...
閱讀 2169·2023-04-25 15:00
閱讀 2343·2021-11-18 13:14
閱讀 1154·2021-11-15 11:37
閱讀 3083·2021-09-24 13:55
閱讀 1221·2019-08-30 15:52
閱讀 2644·2019-08-29 12:35
閱讀 3359·2019-08-29 11:04
閱讀 1209·2019-08-26 12:13