溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Laravel的生命周期是什么

發(fā)布時(shí)間:2021-03-12 10:36:24 來(lái)源:億速云 閱讀:205 作者:小新 欄目:編程語(yǔ)言

小編給大家分享一下Laravel的生命周期是什么,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

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模式。

  1. 當(dāng)我們?cè)诮K端敲入php這個(gè)命令的時(shí)候,使用的是CLI模式。

  2. 當(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è)階段的生命周期切換:

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

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

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

  4. 請(qǐng)求處理完成(Request Shutdown),按順序調(diào)用各個(gè)模塊的 RSHUTDOWN 方法,對(duì)每個(gè)變量調(diào)用 unset函數(shù),如 unset $_SESSION 變量。

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

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

  1. CLI 模式會(huì)在每次腳本執(zhí)行經(jīng)歷完整的5個(gè)周期,因?yàn)槟隳_本執(zhí)行完不會(huì)有下一個(gè)請(qǐng)求;

  2. WEB模式為了應(yīng)對(duì)并發(fā),可能采用多線程,因此生命周期15有可能只執(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è)階段:

Laravel的生命周期是什么

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。理解這些概念,是寫高質(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é)束。

Laravel的生命周期是什么

請(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)加載需要的類

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

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

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

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

Laravel的生命周期是什么

Laravel 的請(qǐng)求步驟

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

第一步:注冊(cè)加載composer自動(dòng)生成的class loader

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

第二步:生成容器 Container

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

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

請(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ù)容器的門面,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;而ServiceProvidersregister方法永遠(yuǎn)先于boot方法執(zhí)行,以免產(chǎn)生boot方法依賴某個(gè)實(shí)例而該實(shí)例還未注冊(cè)的現(xiàn)象。

HTTP 內(nèi)核還定義了一系列所有請(qǐng)求在處理前需要經(jīng)過(guò)的 HTTP 中間件,這些中間件處理 HTTP 會(huì)話的讀寫、判斷應(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)。

第四步:將請(qǐ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á)你寫的代碼之前,Laravel已經(jīng)做了大量工作,請(qǐng)求也經(jīng)過(guò)了千難萬(wàn)險(xiǎn),那些不符合或者惡意的的請(qǐng)求已被Laravel隔離在外。

Laravel的生命周期是什么

看完了這篇文章,相信你對(duì)“Laravel的生命周期是什么”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI