Laravel源码入门-启动引导过程(四)app/Http/Kernel.php
2019獨角獸企業重金招聘Python工程師標準>>>
== 回顧 ==
再來回顧一下 public/index.php ,代碼如下(去掉詳細注釋部分)。
<?php // public/index.php/*** Laravel - A PHP Framework For Web Artisans** @package Laravel* @author Taylor Otwell <taylor@laravel.com>*//* |-------------------------------------------------------------------------- | Register The Auto Loader 注冊類自動載入 |-------------------------------------------------------------------------- | */require __DIR__.'/../bootstrap/autoload.php';/* |-------------------------------------------------------------------------- | Turn On The Lights 開燈點亮(創建$app實例) |-------------------------------------------------------------------------- | */$app = require_once __DIR__.'/../bootstrap/app.php';/* |-------------------------------------------------------------------------- | Run The Application 讓應用跑起來 |-------------------------------------------------------------------------- | */$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);// 博文注釋 // $kernel = $app->make(App\Http\Kernel::class); // dump($kernel);$response = $kernel->handle($request = Illuminate\Http\Request::capture() );$response->send();$kernel->terminate($request, $response);前文詳細分析了 bootstrap/autoload.php 和 bootstrap/app.php,現在來看 $kernel 部分,這里第一行語句令人費解,如下:
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);不理解的地方在于 $kernel 來自于 make() 解析方法,就是說從一個類的名稱中解析出來,而這個類是來自于協議中Http(面向Web,而不是Console)的Kernel,測試發現,實際上解析了 App\Http\Kernel。百思,應該是 bootstrap/app.php 中單例綁定的結果,?綁定語句如下:
$app->singleton(Illuminate\Contracts\Http\Kernel::class,App\Http\Kernel::class );這個 singleton() 將 協議中的Kernel 綁定到 App\Http\Kernel,也就出現了上面 make() 協議的Kernel也就是解析了App\Http\Kernel。這樣做顯然有個好處是,不管我們綁定哪個 Kernel,都可以實現 make() 到。
== 深入 App\Http\Kernel?==
?看看位置先,然后進入源代碼。
?
?
?
<?phpnamespace App\Http;use Illuminate\Foundation\Http\Kernel as HttpKernel;class Kernel extends HttpKernel {/*** The application's global HTTP middleware stack.** These middleware are run during every request to your application.** @var array*/protected $middleware = [\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,\App\Http\Middleware\TrimStrings::class,\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,];/*** The application's route middleware groups.** @var array*/protected $middlewareGroups = ['web' => [\App\Http\Middleware\EncryptCookies::class,\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,\Illuminate\Session\Middleware\StartSession::class,// \Illuminate\Session\Middleware\AuthenticateSession::class,\Illuminate\View\Middleware\ShareErrorsFromSession::class,\App\Http\Middleware\VerifyCsrfToken::class,\Illuminate\Routing\Middleware\SubstituteBindings::class,],'api' => ['throttle:60,1','bindings',],];/*** The application's route middleware.** These middleware may be assigned to groups or used individually.** @var array*/protected $routeMiddleware = ['auth' => \Illuminate\Auth\Middleware\Authenticate::class,'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,'can' => \Illuminate\Auth\Middleware\Authorize::class,'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,]; }從源代碼看到,App\Http\Kernel 繼承自,核心基礎庫的 Illuminate\Foundation\Http\Kernel(以別名HttpKernel 出現),核心庫 Kernel 的代碼如下:
<?php // laravel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.phpnamespace Illuminate\Foundation\Http;// 此處省略 use ...class Kernel implements KernelContract {/*** The application implementation.** @var \Illuminate\Contracts\Foundation\Application*/protected $app;/*** The router instance.** @var \Illuminate\Routing\Router*/protected $router;/*** The bootstrap classes for the application.* 引導類,起引導作用的類* 這些類里面基本上都有一個 bootstrap(Application $app) 方法,* 從不同的角度 bootstrap 應用。為最終 boot() 最準備。* 注意:這些事做不完,不能接受請求,或許連$request都無法正確生成。** @var array*/protected $bootstrappers = [// 載入服務器環境變量(.env 文件?)\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,// 載入配置信息(config 目錄?)\Illuminate\Foundation\Bootstrap\LoadConfiguration::class,// 配置如何處理異常\Illuminate\Foundation\Bootstrap\HandleExceptions::class,// 注冊 Facades\Illuminate\Foundation\Bootstrap\RegisterFacades::class,// 注冊 Providers\Illuminate\Foundation\Bootstrap\RegisterProviders::class,// 啟動 Providers\Illuminate\Foundation\Bootstrap\BootProviders::class,];/*** The application's middleware stack.** @var array*/protected $middleware = [];/*** The application's route middleware groups.** @var array*/protected $middlewareGroups = [];/*** The application's route middleware.** @var array*/protected $routeMiddleware = [];Kernel 中還定義了重要的中間件列表,所有的請求 request 在被應用處理前,都必須經過這些中間件,篩過一遍后,才會被決定如何處理。這涉及到中間件(middleware)的作用。見 Kernel.php 中定義的中間件列表。
<?php // App\Http\Kernel.phpnamespace App\Http;use Illuminate\Foundation\Http\Kernel as HttpKernel;class Kernel extends HttpKernel {/*** The application's global HTTP middleware stack.* 應用全局范圍的 HTTP中間件** These middleware are run during every request to your application.** @var array*/protected $middleware = [// 檢查是否出于維護模式\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,// 檢查Post請求尺寸,太大報異常\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,// 除了密碼外,都要trim — 去除字符串首尾處的空白字符(或者其他字符)\App\Http\Middleware\TrimStrings::class,// 轉換空string('')為null。\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,// 以上這些類似于TP的公共函數 common,不過LA除了稱其為中間件外,更進行了細分];/*** The application's route middleware groups.* 路由中間件(數)組** @var array*/protected $middlewareGroups = ['web' => [// 加密Cookies:是否加密,例外處理等,繼承自\Illuminate\Cookie的中間件\App\Http\Middleware\EncryptCookies::class,// Response頭加入Cookies信息。\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,// 會話的中間件\Illuminate\Session\Middleware\StartSession::class,// \Illuminate\Session\Middleware\AuthenticateSession::class,// 視圖的中間件\Illuminate\View\Middleware\ShareErrorsFromSession::class,// 驗證跨站請求偽造,我們的認識別停留在csrf層面,這些中間件就是處理請求的,// 一定要想辦法處理偽造請求,La用中間件方式做了。\App\Http\Middleware\VerifyCsrfToken::class,// 路由替換綁定~~~???\Illuminate\Routing\Middleware\SubstituteBindings::class,// 上面的類都有一個 handle($request, Closure $next),就是使用自己定義// 的規則對路由進行處理,然后安全了或者符合要求了 return $next($request)。],'api' => ['throttle:60,1','bindings',],];/*** The application's route middleware.** These middleware may be assigned to groups or used individually.** @var array*/protected $routeMiddleware = [// 驗證用戶用'auth' => \Illuminate\Auth\Middleware\Authenticate::class,// 基本驗證:用 email 和 password 方式?'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,// 替換?TP 有 replace,一樣?'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,// 用戶權限,這個是比較具體的了,開發用到了'can' => \Illuminate\Auth\Middleware\Authorize::class,'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,]; }上面的 $middleware[] 是面向全局的,特別是針對 HTTP 的,較為底層的?后面的 $middlewareGroups[] 和 $routeMiddleware[] 是比較具體的實施層面的。應該是可以根據開發需要繼續添加。
總之,Kernel 做了兩件事,第一個是定義 $bootstraps[],做好了 boot 系統的準備,第二個是定義 各種 middleware,這些都對 $request 進行加工、處理、甄選、判斷,最終為可以形成正確的、有效的 $response 做準備,都完成后,進行了 index.php 中的 $kernel->handle($request),返回 $response。
== 總結 ==?
$request --->?$kernel { service providers/middlewares/routers?}?---> $response
Kernel 是就是個大黑箱,送入請求,輸出響應,我們只管往里面添加服務、中間件、路由等等。? ? ? ? ? ? ? ??
?
轉載于:https://my.oschina.net/zhmsong/blog/898986
總結
以上是生活随笔為你收集整理的Laravel源码入门-启动引导过程(四)app/Http/Kernel.php的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浴火银河星际跳跃(并查集)
- 下一篇: 十分简洁的手机浏览器 lydiabox