世間萬物皆有生命週期,當咱們使用任何工具時都須要理解它的工做原理,那麼用起來就會駕輕就熟,應用開發也是如此。理解了它的原理,那麼使用起來就會遊刃有餘。php
在瞭解 Laravel 的生命週期前,咱們先回顧一下PHP 的生命週期。mysql
PHP兩種運行模式是WEB模式、CLI模式。laravel
當咱們請求一個php
文件時,PHP 爲了完成此次請求,會發生5個階段的生命週期切換:web
模塊初始化(MINIT),即調用 php.ini
中指明的擴展的初始化函數進行初始化工做,如 mysql
擴展。sql
請求初始化(RINIT),即初始化爲執行本次腳本所須要的變量名稱和變量值內容的符號表,如 $_SESSION
變量。bootstrap
執行該PHP腳本。數組
請求處理完成(Request Shutdown),按順序調用各個模塊的 RSHUTDOWN
方法,對每一個變量調用 unset
函數,如 unset $_SESSION
變量。瀏覽器
關閉模塊(Module Shutdown) , PHP調用每一個擴展的 MSHUTDOWN
方法,這是各個模塊最後一次釋放內存的機會。這意味着沒有下一個請求了。bash
WEB模式和CLI(命令行)模式很類似,區別是:服務器
1
和5
有可能只執行一次,下次請求到來時重複2-4
的生命週期,這樣就節省了系統模塊初始化所帶來的開銷。能夠看出PHP生命週期是很對稱的。說了這麼多,就是爲了定位Laravel運行在哪裏,沒錯,Laravel僅僅運行再 第三個階段:
PHP生命週期理解這些,你就能夠優化你的 Laravel
代碼,能夠更加深刻的瞭解 Laravel 的singleton
(單例)。至少你知道了,每一次請求結束,PHP 的變量都會 unset
,Laravel 的 singleton
只是在某一次請求過程當中的singleton
;你在 Laravel 中的靜態變量也不能在多個請求之間共享,由於每一次請求結束都會 unset
。理解這些概念,是寫高質量代碼的第一步,也是最關鍵的一步。所以記住,PHP是一種腳本語言,全部的變量只會在這一次請求中生效,下次請求之時已被重置,而不像Java靜態變量擁有全局做用。
Laravel 的生命週期從public\index.php
開始,從public\index.php
結束。
下面是 public\index.php
的所有源碼,更具體來講能夠分爲四步:
1. require __DIR__.'/../bootstrap/autoload.php';
2. $app = require_once __DIR__.'/../bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
3. $response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
$response->send();
4. $kernel->terminate($request, $response);
複製代碼
composer自動加載須要的類
composer require
的依賴。咱們不妨在詳細一點:
class loader
就是加載初始化第三方依賴。
Container
並向容器註冊核心組件,是從 bootstrap/app.php
腳本獲取 Laravel 應用實例,
請求被髮送到 HTTP
內核或 Console
內核,這取決於進入應用的請求類型。
取決因而經過瀏覽器請求仍是經過控制檯請求。這裏咱們主要是經過瀏覽器請求。
HTTP 內核繼承自 Illuminate\Foundation\Http\Kernel 類,該類定義了一個 bootstrappers 數組,這個數組中的類在請求被執行前運行,這些 bootstrappers 配置了錯誤處理、日誌、檢測應用環境以及其它在請求被處理前須要執行的任務。
protected $bootstrappers = [
//註冊系統環境配置 (.env)
'Illuminate\Foundation\Bootstrap\DetectEnvironment',
//註冊系統配置(config)
'Illuminate\Foundation\Bootstrap\LoadConfiguration',
//註冊日誌配置
'Illuminate\Foundation\Bootstrap\ConfigureLogging',
//註冊異常處理
'Illuminate\Foundation\Bootstrap\HandleExceptions',
//註冊服務容器的門面,Facade 是個提供從容器訪問對象的類。
'Illuminate\Foundation\Bootstrap\RegisterFacades',
//註冊服務提供者
'Illuminate\Foundation\Bootstrap\RegisterProviders',
//註冊服務提供者 `boot`
'Illuminate\Foundation\Bootstrap\BootProviders',
];
複製代碼
注意順序:
Facades
先於ServiceProviders
,Facades
也是重點,後面說,這裏簡單提一下,註冊Facades
就是註冊config\app.php
中的aliases
數組,你使用的不少類,如Auth
,Cache
,DB
等等都是Facades
;而ServiceProviders
的register
方法永遠先於boot
方法執行,以避免產生boot
方法依賴某個實例而該實例還未註冊的現象。
HTTP 內核還定義了一系列全部請求在處理前須要通過的 HTTP 中間件,這些中間件處理 HTTP 會話的讀寫、判斷應用是否處於維護模式、驗證 CSRF 令牌等等。
HTTP 內核的標誌性方法 handle處理的邏輯至關簡單:獲取一個
Request
,返回一個Response
,把該內核想象做一個表明整個應用的大黑盒子,輸入 HTTP 請求,返回 HTTP 響應。
在Laravel基礎的服務啓動以後,就要把請求傳遞給路由了。路由器將會分發請求到路由或控制器,同時運行全部路由指定的中間件。
傳遞給路由是經過 Pipeline
(管道)來傳遞的,可是Pipeline有一堵牆,在傳遞給路由以前全部請求都要通過,這堵牆定義在app\Http\Kernel.php
中的$middleware
數組中,沒錯就是中間件,默認只有一個CheckForMaintenanceMode
中間件,用來檢測你的網站是否暫時關閉。這是一個全局中間件,全部請求都要通過,你也能夠添加本身的全局中間件。
而後遍歷全部註冊的路由,找到最早符合的第一個路由,通過它的路由中間件,進入到控制器或者閉包函數,執行你的具體邏輯代碼。
因此,當請求到達你寫的代碼以前,Laravel已經作了大量工做,請求也通過了千難萬險,那些不符合或者惡意的的請求已被Laravel隔離在外。
處理請求到響應過程本文來自:簡書
感謝做者:伊Summer
查看原文:Laravel 的生命週期