小編給大家分享一下Laravel的生命周期是什么,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
創(chuàng)新互聯(lián)公司主要從事網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)洪山,十余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來(lái)電咨詢建站服務(wù):13518219792
Laravel的生命周期
世間萬(wàn)物皆有生命周期,當(dāng)我們使用任何工具時(shí)都需要理解它的工作原理,那么用起來(lái)就會(huì)得心應(yīng)手,應(yīng)用開(kāi)發(fā)也是如此。理解了它的原理,那么使用起來(lái)就會(huì)游刃有余。
在了解 Laravel 的生命周期前,我們先回顧一下PHP 的生命周期。
PHP 的生命周期
PHP 的運(yùn)行模式
PHP兩種運(yùn)行模式是WEB模式、CLI模式。
當(dāng)我們?cè)诮K端敲入php這個(gè)命令的時(shí)候,使用的是CLI模式。
當(dāng)使用Nginx或者別web服務(wù)器作為宿主處理一個(gè)到來(lái)的請(qǐng)求時(shí),使用的是WEB模式。
生命周期
當(dāng)我們請(qǐng)求一個(gè)php
文件時(shí),PHP 為了完成這次請(qǐng)求,會(huì)發(fā)生5個(gè)階段的生命周期切換:
模塊初始化(MINIT),即調(diào)用 php.ini
中指明的擴(kuò)展的初始化函數(shù)進(jìn)行初始化工作,如 MySQL
擴(kuò)展。
請(qǐng)求初始化(RINIT),即初始化為執(zhí)行本次腳本所需要的變量名稱和變量值內(nèi)容的符號(hào)表,如 $_SESSION
變量。
執(zhí)行該P(yáng)HP腳本。
請(qǐng)求處理完成(Request Shutdown),按順序調(diào)用各個(gè)模塊的 RSHUTDOWN
方法,對(duì)每個(gè)變量調(diào)用 unset
函數(shù),如 unset $_SESSION
變量。
關(guān)閉模塊(Module Shutdown) , PHP調(diào)用每個(gè)擴(kuò)展的 MSHUTDOWN
方法,這是各個(gè)模塊最后一次釋放內(nèi)存的機(jī)會(huì)。這意味著沒(méi)有下一個(gè)請(qǐng)求了。
WEB模式和CLI(命令行)模式很相似,區(qū)別是:
CLI 模式會(huì)在每次腳本執(zhí)行經(jīng)歷完整的5個(gè)周期,因?yàn)槟隳_本執(zhí)行完不會(huì)有下一個(gè)請(qǐng)求;
WEB模式為了應(yīng)對(duì)并發(fā),可能采用多線程,因此生命周期1
和5
有可能只執(zhí)行一次,下次請(qǐng)求到來(lái)時(shí)重復(fù)2-4
的生命周期,這樣就節(jié)省了系統(tǒng)模塊初始化所帶來(lái)的開(kāi)銷。
可以看出PHP生命周期是很對(duì)稱的。說(shuō)了這么多,就是為了定位Laravel運(yùn)行在哪里,沒(méi)錯(cuò),Laravel僅僅運(yùn)行再 第三個(gè)階段:
PHP生命周期
作用
理解這些,你就可以優(yōu)化你的 Laravel
代碼,可以更加深入的了解 Laravel 的singleton
(單例)。至少你知道了,每一次請(qǐng)求結(jié)束,PHP 的變量都會(huì) unset
,Laravel 的 singleton
只是在某一次請(qǐng)求過(guò)程中的singleton
;你在 Laravel 中的靜態(tài)變量也不能在多個(gè)請(qǐng)求之間共享,因?yàn)槊恳淮握?qǐng)求結(jié)束都會(huì) unset
。理解這些概念,是寫(xiě)高質(zhì)量代碼的第一步,也是最關(guān)鍵的一步。因此記住,PHP是一種腳本語(yǔ)言,所有的變量只會(huì)在這一次請(qǐng)求中生效,下次請(qǐng)求之時(shí)已被重置,而不像Java靜態(tài)變量擁有全局作用。
Laravel 的生命周期
概述
Laravel 的生命周期從public\index.php
開(kāi)始,從public\index.php
結(jié)束。
請(qǐng)求過(guò)程
下面是 public\index.php
的全部源碼,更具體來(lái)說(shuō)可以分為四步:
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自動(dòng)加載需要的類
文件載入composer生成的自動(dòng)加載設(shè)置,包括所有你 composer require
的依賴。
生成容器Container,Application實(shí)例,并向容器注冊(cè)核心組件(HttpKernel,ConsoleKernel ,ExceptionHandler)(對(duì)應(yīng)代碼2,容器很重要,后面詳細(xì)講解)。
處理請(qǐng)求,生成并發(fā)送響應(yīng)(對(duì)應(yīng)代碼3,毫不夸張的說(shuō),你99%的代碼都運(yùn)行在這個(gè)小小的handle 方法里面)。
請(qǐng)求結(jié)束,進(jìn)行回調(diào)(對(duì)應(yīng)代碼4,還記得可終止中間件嗎?沒(méi)錯(cuò),就是在這里回調(diào)的)。
Laravel 的請(qǐng)求步驟
我們不妨在詳細(xì)一點(diǎn):
class loader
就是加載初始化第三方依賴。
Container
并向容器注冊(cè)核心組件,是從 bootstrap/app.php
腳本獲取 Laravel 應(yīng)用實(shí)例,
請(qǐng)求被發(fā)送到 HTTP
內(nèi)核或 Console
內(nèi)核,這取決于進(jìn)入應(yīng)用的請(qǐng)求類型。
取決于是通過(guò)瀏覽器請(qǐng)求還是通過(guò)控制臺(tái)請(qǐng)求。這里我們主要是通過(guò)瀏覽器請(qǐng)求。
HTTP 內(nèi)核繼承自 Illuminate\Foundation\Http\Kernel 類,該類定義了一個(gè) bootstrappers 數(shù)組,這個(gè)數(shù)組中的類在請(qǐng)求被執(zhí)行前運(yùn)行,這些 bootstrappers 配置了錯(cuò)誤處理、日志、檢測(cè)應(yīng)用環(huán)境以及其它在請(qǐng)求被處理前需要執(zhí)行的任務(wù)。
protected $bootstrappers = [ //注冊(cè)系統(tǒng)環(huán)境配置 (.env) 'Illuminate\Foundation\Bootstrap\DetectEnvironment', //注冊(cè)系統(tǒng)配置(config) 'Illuminate\Foundation\Bootstrap\LoadConfiguration', //注冊(cè)日志配置 'Illuminate\Foundation\Bootstrap\ConfigureLogging', //注冊(cè)異常處理 'Illuminate\Foundation\Bootstrap\HandleExceptions', //注冊(cè)服務(wù)容器的門(mén)面,F(xiàn)acade 是個(gè)提供從容器訪問(wèn)對(duì)象的類。 'Illuminate\Foundation\Bootstrap\RegisterFacades', //注冊(cè)服務(wù)提供者 'Illuminate\Foundation\Bootstrap\RegisterProviders', //注冊(cè)服務(wù)提供者 `boot` 'Illuminate\Foundation\Bootstrap\BootProviders', ];
注意順序:
Facades
先于ServiceProviders
,Facades
也是重點(diǎn),后面說(shuō),這里簡(jiǎn)單提一下,注冊(cè)Facades
就是注冊(cè)config\app.php
中的aliases
數(shù)組,你使用的很多類,如Auth
,Cache
,DB
等等都是Facades
;而ServiceProviders
的register
方法永遠(yuǎn)先于boot
方法執(zhí)行,以免產(chǎn)生boot
方法依賴某個(gè)實(shí)例而該實(shí)例還未注冊(cè)的現(xiàn)象。
HTTP 內(nèi)核還定義了一系列所有請(qǐng)求在處理前需要經(jīng)過(guò)的 HTTP 中間件,這些中間件處理 HTTP 會(huì)話的讀寫(xiě)、判斷應(yīng)用是否處于維護(hù)模式、驗(yàn)證 CSRF 令牌等等。
HTTP 內(nèi)核的標(biāo)志性方法 handle處理的邏輯相當(dāng)簡(jiǎn)單:獲取一個(gè)
Request
,返回一個(gè)Response
,把該內(nèi)核想象作一個(gè)代表整個(gè)應(yīng)用的大黑盒子,輸入 HTTP 請(qǐng)求,返回 HTTP 響應(yīng)。
在Laravel基礎(chǔ)的服務(wù)啟動(dòng)之后,就要把請(qǐng)求傳遞給路由了。路由器將會(huì)分發(fā)請(qǐng)求到路由或控制器,同時(shí)運(yùn)行所有路由指定的中間件。
傳遞給路由是通過(guò) Pipeline
(管道)來(lái)傳遞的,但是Pipeline有一堵墻,在傳遞給路由之前所有請(qǐng)求都要經(jīng)過(guò),這堵墻定義在app\Http\Kernel.php
中的$middleware
數(shù)組中,沒(méi)錯(cuò)就是中間件,默認(rèn)只有一個(gè)CheckForMaintenanceMode
中間件,用來(lái)檢測(cè)你的網(wǎng)站是否暫時(shí)關(guān)閉。這是一個(gè)全局中間件,所有請(qǐng)求都要經(jīng)過(guò),你也可以添加自己的全局中間件。
然后遍歷所有注冊(cè)的路由,找到最先符合的第一個(gè)路由,經(jīng)過(guò)它的路由中間件,進(jìn)入到控制器或者閉包函數(shù),執(zhí)行你的具體邏輯代碼。
所以,當(dāng)請(qǐng)求到達(dá)你寫(xiě)的代碼之前,Laravel已經(jīng)做了大量工作,請(qǐng)求也經(jīng)過(guò)了千難萬(wàn)險(xiǎn),那些不符合或者惡意的的請(qǐng)求已被Laravel隔離在外。
看完了這篇文章,相信你對(duì)“Laravel的生命周期是什么”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!