在\bootstrap\app.php文件中:php
$app->singleton( Illuminate\Contracts\Http\Kernel::class, App\Http\Kernel::class ); $app->singleton( Illuminate\Contracts\Console\Kernel::class, App\Console\Kernel::class ); $app->singleton( Illuminate\Contracts\Debug\ExceptionHandler::class, App\Exceptions\Handler::class );
App\Http\Kernel::class(中間件)laravel
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, \App\Http\Middleware\TrustProxies::class, ];
\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.phpbootstrap
protected function sendRequestThroughRouter($request) { $this->app->instance('request', $request); Facade::clearResolvedInstance('request'); //針對請求爲應用程序'拔靴帶' 執行bootstrap類的數組 //在請求處理階段共有7個環節,每個環節由一個類來實現的 //並且每一個類都會有一個bootstrap()函數用於實現準備工做 $this->bootstrap(); return (new Pipeline($this->app)) ->send($request) ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware) ->then($this->dispatchToRouter()); }
/** * Get the route dispatcher callback. *設置路由分發回調函數 * @return \Closure */ protected function dispatchToRouter() { return function ($request) { $this->app->instance('request', $request); return $this->router->dispatch($request); }; }
\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php數組
/** * Set the object being sent through the pipeline. *設置被送入管道的對象 * @param mixed $passable * @return $this */ public function send($passable) { $this->passable = $passable; return $this; }
/** * Set the array of pipes. *設置導管數組 * @param array|mixed $pipes * @return $this */ public function through($pipes) { $this->pipes = is_array($pipes) ? $pipes : func_get_args(); return $this; }
/** * 以一個回調函數爲終點執行管道處理 */ public function then(Closure $destination) { $pipeline = array_reduce( array_reverse($this->pipes), $this->carry(), $this->prepareDestination($destination) ); return $pipeline($this->passable); }
/** * 獲取一個用來代替洋蔥層的回調函數 * * @return \Closure */ protected function carry() { return function ($stack, $pipe) { return function ($passable) use ($stack, $pipe) { if (is_callable($pipe)) { return $pipe($passable, $stack); } elseif (! is_object($pipe)) { list($name, $parameters) = $this->parsePipeString($pipe); $pipe = $this->getContainer()->make($name); $parameters = array_merge([$passable, $stack], $parameters); } else { $parameters = [$passable, $stack]; } return method_exists($pipe, $this->method) ? $pipe->{$this->method}(...$parameters) : $pipe(...$parameters); }; }; }
在 Laravel 框架中,不少註釋和代碼名稱已經很是形象地表達了程序代碼的功能,代碼註釋中將中間件稱爲「洋蔥」層,將整個處理流程稱爲「管道」,有些地方會用到這些名詞,若是讀者理解了真正的含義就會更容易理解程序。對清求的處理階段, l1 ’先對管道類( Pipelinc 類)進行了實例化,分別經過 send ( )函數和 through ( )函數將請求實例和中間件數組賦值給管道實例,而鼓終的處理是經過 theno 函數完成的,該函數有一個參數,這個參數是通過「管道」後的終點處理函數,即下~步的路由處理。而 theno 函數其實就是將整個中間件數組經過服務容器’仁成實例,並對這些實例的 handlco 函數和傳入的終點處理 l " l 調函數進行組裝,造成一個遞歸調用的回調函數,再進行調用,最終完成「管道」的逐級處理app