Laravel 的生命周期

世間萬物皆有生命周期潮瓶,當(dāng)我們使用任何工具時都需要理解它的工作原理,那么用起來就會得心應(yīng)手毯辅,應(yīng)用開發(fā)也是如此。理解了它的原理思恐,那么使用起來就會游刃有余。
在了解 Laravel 的生命周期前基跑,我們先回顧一下PHP 的生命周期。

PHP 的生命周期

PHP 的運(yùn)行模式

PHP兩種運(yùn)行模式是WEB模式媳否、CLI模式。

  1. 當(dāng)我們在終端敲入php這個命令的時候篱竭,使用的是CLI模式力图。
  2. 當(dāng)使用Nginx或者別web服務(wù)器作為宿主處理一個到來的請求時,使用的是WEB模式掺逼。

生命周期

當(dāng)我們請求一個php文件時,PHP 為了完成這次請求,會發(fā)生5個階段的生命周期切換:

  1. 模塊初始化(MINIT)吕喘,即調(diào)用 php.ini 中指明的擴(kuò)展的初始化函數(shù)進(jìn)行初始化工作,如 mysql 擴(kuò)展兽泄。

  2. 請求初始化(RINIT),即初始化為執(zhí)行本次腳本所需要的變量名稱和變量值內(nèi)容的符號表病梢,如 $_SESSION變量。

  3. 執(zhí)行該P(yáng)HP腳本蜓陌。

  4. 請求處理完成(Request Shutdown),按順序調(diào)用各個模塊的 RSHUTDOWN 方法填抬,對每個變量調(diào)用 unset函數(shù),如 unset $_SESSION 變量飒责。

  5. 關(guān)閉模塊(Module Shutdown) , PHP調(diào)用每個擴(kuò)展的 MSHUTDOWN 方法宏蛉,這是各個模塊最后一次釋放內(nèi)存的機(jī)會。這意味著沒有下一個請求了拾并。

WEB模式和CLI(命令行)模式很相似,區(qū)別是:

  1. CLI 模式會在每次腳本執(zhí)行經(jīng)歷完整的5個周期嗅义,因?yàn)槟隳_本執(zhí)行完不會有下一個請求隐砸;
  2. WEB模式為了應(yīng)對并發(fā)之碗,可能采用多線程凰萨,因此生命周期15有可能只執(zhí)行一次械馆,下次請求到來時重復(fù)2-4的生命周期,這樣就節(jié)省了系統(tǒng)模塊初始化所帶來的開銷霹崎。

可以看出PHP生命周期是很對稱的冶忱。說了這么多尾菇,就是為了定位Laravel運(yùn)行在哪里囚枪,沒錯,Laravel僅僅運(yùn)行再 第三個階段:

PHP生命周期

作用

理解這些链沼,你就可以優(yōu)化你的 Laravel 代碼,可以更加深入的了解 Laravel 的singleton(單例)括勺。至少你知道了,每一次請求結(jié)束疾捍,PHP 的變量都會 unset,Laravel 的 singleton 只是在某一次請求過程中的singleton乱豆;你在 Laravel 中的靜態(tài)變量也不能在多個請求之間共享,因?yàn)槊恳淮握埱蠼Y(jié)束都會 unset宛裕。理解這些概念,是寫高質(zhì)量代碼的第一步翰守,也是最關(guān)鍵的一步。因此記住,PHP是一種腳本語言了袁,所有的變量只會在這一次請求中生效,下次請求之時已被重置载绿,而不像Java靜態(tài)變量擁有全局作用。

Laravel 的生命周期

概述

Laravel 的生命周期從public\index.php開始崭庸,從public\index.php結(jié)束谊囚。

請求過程

下面是 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);

以下是四步詳細(xì)的解釋是:
composer自動加載需要的類

  1. 文件載入composer生成的自動加載設(shè)置执赡,包括所有你 composer require的依賴镰踏。

  2. 生成容器Container沙合,Application實(shí)例,并向容器注冊核心組件(HttpKernel首懈,ConsoleKernel ,ExceptionHandler)(對應(yīng)代碼2究履,容器很重要,后面詳細(xì)講解)最仑。

  3. 處理請求,生成并發(fā)送響應(yīng)(對應(yīng)代碼3盯仪,毫不夸張的說,你99%的代碼都運(yùn)行在這個小小的handle 方法里面)全景。

  4. 請求結(jié)束,進(jìn)行回調(diào)(對應(yīng)代碼4爸黄,還記得可終止中間件嗎?沒錯梆奈,就是在這里回調(diào)的)。

Laravel 的請求步驟

我們不妨在詳細(xì)一點(diǎn):

第一步:注冊加載composer自動生成的class loader

就是加載初始化第三方依賴亩钟。

第二步:生成容器 Container

并向容器注冊核心組件鳖轰,是從 bootstrap/app.php 腳本獲取 Laravel 應(yīng)用實(shí)例清酥,

第三步:這一步是重點(diǎn)蕴侣,處理請求,并生成發(fā)送響應(yīng)昆雀。

請求被發(fā)送到 HTTP 內(nèi)核或 Console 內(nèi)核蝠筑,這取決于進(jìn)入應(yīng)用的請求類型。

取決于是通過瀏覽器請求還是通過控制臺請求什乙。這里我們主要是通過瀏覽器請求。

HTTP 內(nèi)核的標(biāo)志性方法 handle處理的邏輯相當(dāng)簡單:獲取一個 Request稳强,返回一個 Response,把該內(nèi)核想象作一個代表整個應(yīng)用的大黑盒子退疫,輸入 HTTP 請求,返回 HTTP 響應(yīng)褒繁。

1. 首先 Bootstrap 檢測環(huán)境馍忽,加載 bootstrapper數(shù)組中的一些配置

HTTP 內(nèi)核繼承自 Illuminate\Foundation\Http\Kernel 類棒坏,該類定義了一個 bootstrappers 數(shù)組遭笋,這個數(shù)組中的類在請求被執(zhí)行前運(yùn)行,這些 bootstrappers 配置了錯誤處理瓦呼、日志、檢測應(yīng)用環(huán)境以及其它在請求被處理前需要執(zhí)行的任務(wù)央串。

protected $bootstrappers = [
        //注冊系統(tǒng)環(huán)境配置 (.env)
        'Illuminate\Foundation\Bootstrap\DetectEnvironment',
        //注冊系統(tǒng)配置(config)
        'Illuminate\Foundation\Bootstrap\LoadConfiguration',
        //注冊日志配置
        'Illuminate\Foundation\Bootstrap\ConfigureLogging',
        //注冊異常處理
        'Illuminate\Foundation\Bootstrap\HandleExceptions',
        //注冊服務(wù)容器的門面,F(xiàn)acade 是個提供從容器訪問對象的類质和。
        'Illuminate\Foundation\Bootstrap\RegisterFacades',
        //注冊服務(wù)提供者
        'Illuminate\Foundation\Bootstrap\RegisterProviders',
        //注冊服務(wù)提供者 `boot`
        'Illuminate\Foundation\Bootstrap\BootProviders',
    ];

注意順序:
Facades 先于ServiceProvidersFacades也是重點(diǎn)饲宿,后面說,這里簡單提一下瘫想,注冊 Facades 就是注冊 config\app.php中的aliases 數(shù)組,你使用的很多類殿托,如Auth剧蚣,Cache,DB等等都是Facades旋廷;而ServiceProvidersregister方法永遠(yuǎn)先于boot方法執(zhí)行,以免產(chǎn)生boot方法依賴某個實(shí)例而該實(shí)例還未注冊的現(xiàn)象饶碘。

HTTP 內(nèi)核還定義了一系列所有請求在處理前需要經(jīng)過的 HTTP 中間件馒吴,這些中間件處理 HTTP 會話的讀寫扎运、判斷應(yīng)用是否處于維護(hù)模式饮戳、驗(yàn)證 CSRF 令牌等等。

2. 第一堵墻扯罐,全局中間件,默認(rèn)為 CheckForMaintenanceMode

在Laravel基礎(chǔ)的服務(wù)啟動之后歹河,就要把請求傳遞給路由了。路由器將會分發(fā)請求到路由或控制器秸歧,同時運(yùn)行所有路由指定的中間件。

傳遞方式

傳遞給路由是通過 Pipeline(管道)來傳遞的键菱,但是Pipeline有一堵墻,在傳遞給路由之前所有請求都要經(jīng)過纱耻,這堵墻定義在app\Http\Kernel.php中的$middleware數(shù)組中,沒錯就是中間件弄喘,默認(rèn)只有一個CheckForMaintenanceMode中間件,用來檢測你的網(wǎng)站是否暫時關(guān)閉蘑志。這是一個全局中間件,所有請求都要經(jīng)過急但,你也可以添加自己的全局中間件。

3. 然后遍歷所有注冊的路由波桩,找到最先符合的第一個路由

然后遍歷所有注冊的路由,找到最先符合的第一個路由镐躲,

4. 第二堵墻侍筛,通過該路由的中間件(組)

經(jīng)過該路由中間件撒穷,進(jìn)入到控制器或者閉包函數(shù)匣椰,執(zhí)行你的具體邏輯代碼端礼。

所以禽笑,當(dāng)請求到達(dá)你寫的代碼之前蛤奥,Laravel已經(jīng)做了大量工作,請求也經(jīng)過了千難萬險喻括,那些不符合或者惡意的的請求已被Laravel隔離在外。

處理請求到響應(yīng)過程
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末望蜡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子脖律,更是在濱河造成了極大的恐慌,老刑警劉巖小泉,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冕杠,死亡現(xiàn)場離奇詭異微姊,居然都是意外死亡分预,警方通過查閱死者的電腦和手機(jī)兢交,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門笼痹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人凳干,你說我怎么就攤上這事【却停” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵少欺,是天一觀的道長喳瓣。 經(jīng)常有香客問我赞别,道長配乓,這世上最難降的妖魔是什么仿滔? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任犹芹,我火速辦了婚禮,結(jié)果婚禮上腰埂,老公的妹妹穿的比我還像新娘。我一直安慰自己屿笼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布驴一。 她就那樣靜靜地躺著,像睡著了一般肝断。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上胸懈,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音趣钱,去河邊找鬼。 笑死羔挡,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的绞灼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼低矮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起昨悼,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤跃洛,失蹤者是張志新(化名)和其女友劉穎率触,沒想到半個月后汇竭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體葱蝗,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡细燎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了玻驻。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡户辫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出彪蓬,到底是詐尸還是另有隱情,我是刑警寧澤档冬,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站披坏,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏盐数。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一帚屉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧漾峡,春花似錦、人聲如沸生逸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锋谐。三九已至截酷,卻和暖如春涮拗,著一層夾襖步出監(jiān)牢的瞬間迂苛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工灾部, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惯退,地道東北人赌髓。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓催跪,卻偏偏與公主長得像,于是被迫代替她去往敵國和親懊蒸。 傳聞我的和親對象是個殘疾皇子荣倾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理舌仍,服務(wù)發(fā)現(xiàn),斷路器通危,智...
    卡卡羅2017閱讀 134,651評論 18 139
  • 原文鏈接 必備品 文檔:Documentation API:API Reference 視頻:Laracasts ...
    layjoy閱讀 8,607評論 0 121
  • laravel生命周期從全部包含在public\index.php文件中
    fireinme閱讀 1,034評論 0 1
  • 0.1配置1.模板繼承2.控制器3.git4.支付寶支付的流程5.路由6.中間件7.請求8.laravel 學(xué)習(xí)筆...
    云龍789閱讀 808評論 0 5
  • 真正的愛是菊碟,明知他/她愛的不是自己,卻仍可以為了他/她逆害,傾盡自己的所有头镊,甚至是性命也在所不惜魄幕。 ...
    愿逐月華留照君閱讀 952評論 0 2