成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Laravel核心解讀--HTTP內(nèi)核

chenjiang3 / 2134人閱讀

摘要:終止程序終止中間件內(nèi)核的方法會(huì)調(diào)用中間件的方法,調(diào)用完成后從請(qǐng)求進(jìn)來(lái)到返回響應(yīng)整個(gè)應(yīng)用程序的生命周期就結(jié)束了。

Http Kernel

Http Kernel是Laravel中用來(lái)串聯(lián)框架的各個(gè)核心組件來(lái)網(wǎng)絡(luò)請(qǐng)求的,簡(jiǎn)單的說(shuō)只要是通過(guò)public/index.php來(lái)啟動(dòng)框架的都會(huì)用到Http Kernel,而另外的類似通過(guò)artisan命令、計(jì)劃任務(wù)、隊(duì)列啟動(dòng)框架進(jìn)行處理的都會(huì)用到Console Kernel, 今天我們先梳理一下Http Kernel做的事情。

內(nèi)核綁定

既然Http Kernel是Laravel中用來(lái)串聯(lián)框架的各個(gè)部分處理網(wǎng)絡(luò)請(qǐng)求的,我們來(lái)看一下內(nèi)核是怎么加載到Laravel中應(yīng)用實(shí)例中來(lái)的,在public/index.php中我們就會(huì)看見(jiàn)首先就會(huì)通過(guò)bootstrap/app.php這個(gè)腳手架文件來(lái)初始化應(yīng)用程序:

下面是 bootstrap/app.php 的代碼,包含兩個(gè)主要部分創(chuàng)建應(yīng)用實(shí)例綁定內(nèi)核至 APP 服務(wù)容器

singleton(
    IlluminateContractsHttpKernel::class,
    AppHttpKernel::class
);

$app->singleton(
    IlluminateContractsConsoleKernel::class,
    AppConsoleKernel::class
);

$app->singleton(
    IlluminateContractsDebugExceptionHandler::class,
    AppExceptionsHandler::class
);

return $app;

HTTP 內(nèi)核繼承自 IlluminateFoundationHttpKernel類,在 HTTP 內(nèi)核中 內(nèi)它定義了中間件相關(guān)數(shù)組, 中間件提供了一種方便的機(jī)制來(lái)過(guò)濾進(jìn)入應(yīng)用的 HTTP 請(qǐng)求和加工流出應(yīng)用的HTTP響應(yīng)。

 [
            AppHttpMiddlewareEncryptCookies::class,
            IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class,
            IlluminateSessionMiddlewareStartSession::class,
            // IlluminateSessionMiddlewareAuthenticateSession::class,
            IlluminateViewMiddlewareShareErrorsFromSession::class,
            AppHttpMiddlewareVerifyCsrfToken::class,
            IlluminateRoutingMiddlewareSubstituteBindings::class,
        ],
        "api" => [
            "throttle:60,1",
            "bindings",
        ],
    ];
    /**
     * The application"s route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        "auth" => IlluminateAuthMiddlewareAuthenticate::class,
        "auth.basic" => IlluminateAuthMiddlewareAuthenticateWithBasicAuth::class,
        "bindings" => IlluminateRoutingMiddlewareSubstituteBindings::class,
        "can" => IlluminateAuthMiddlewareAuthorize::class,
        "guest" => AppHttpMiddlewareRedirectIfAuthenticated::class,
        "throttle" => IlluminateRoutingMiddlewareThrottleRequests::class,
    ];
}

在其父類 「IlluminateFoundationHttpKernel」 內(nèi)部定義了屬性名為 「bootstrappers」 的 引導(dǎo)程序 數(shù)組:

protected $bootstrappers = [
    IlluminateFoundationBootstrapLoadEnvironmentVariables::class,
    IlluminateFoundationBootstrapLoadConfiguration::class,
    IlluminateFoundationBootstrapHandleExceptions::class,
    IlluminateFoundationBootstrapRegisterFacades::class,
    IlluminateFoundationBootstrapRegisterProviders::class,
    IlluminateFoundationBootstrapBootProviders::class,
];

引導(dǎo)程序組中 包括完成環(huán)境檢測(cè)、配置加載、異常處理、Facades 注冊(cè)、服務(wù)提供者注冊(cè)、啟動(dòng)服務(wù)這六個(gè)引導(dǎo)程序。

有關(guān)中間件和引導(dǎo)程序相關(guān)內(nèi)容的講解可以瀏覽我們之前相關(guān)章節(jié)的內(nèi)容。

應(yīng)用解析內(nèi)核

在將應(yīng)用初始化階段將Http內(nèi)核綁定至應(yīng)用的服務(wù)容器后,緊接著在public/index.php中我們可以看到使用了服務(wù)容器的make方法將Http內(nèi)核實(shí)例解析了出來(lái):

$kernel = $app->make(IlluminateContractsHttpKernel::class);

在實(shí)例化內(nèi)核時(shí),將在 HTTP 內(nèi)核中定義的中間件注冊(cè)到了 路由器,注冊(cè)完后就可以在實(shí)際處理 HTTP 請(qǐng)求前調(diào)用路由上應(yīng)用的中間件實(shí)現(xiàn)過(guò)濾請(qǐng)求的目的:

namespace IlluminateFoundationHttp;
...
class Kernel implements KernelContract
{
    /**
     * Create a new HTTP kernel instance.
     *
     * @param  IlluminateContractsFoundationApplication  $app
     * @param  IlluminateRoutingRouter  $router
     * @return void
     */
    public function __construct(Application $app, Router $router)
    {
        $this->app = $app;
        $this->router = $router;

        $router->middlewarePriority = $this->middlewarePriority;

        foreach ($this->middlewareGroups as $key => $middleware) {
            $router->middlewareGroup($key, $middleware);
        }
        
        foreach ($this->routeMiddleware as $key => $middleware) {
            $router->aliasMiddleware($key, $middleware);
        }
    }
}

namespace Illuminate/Routing;
class Router implements RegistrarContract, BindingRegistrar
{
    /**
     * Register a group of middleware.
     *
     * @param  string  $name
     * @param  array  $middleware
     * @return $this
     */
    public function middlewareGroup($name, array $middleware)
    {
        $this->middlewareGroups[$name] = $middleware;

        return $this;
    }
    
    /**
     * Register a short-hand name for a middleware.
     *
     * @param  string  $name
     * @param  string  $class
     * @return $this
     */
    public function aliasMiddleware($name, $class)
    {
        $this->middleware[$name] = $class;

        return $this;
    }
}
處理HTTP請(qǐng)求

通過(guò)服務(wù)解析完成Http內(nèi)核實(shí)例的創(chuàng)建后就可以用HTTP內(nèi)核實(shí)例來(lái)處理HTTP請(qǐng)求了

//public/index.php
$response = $kernel->handle(
    $request = IlluminateHttpRequest::capture()
);

在處理請(qǐng)求之前會(huì)先通過(guò)IlluminateHttpRequestcapture() 方法以進(jìn)入應(yīng)用的HTTP請(qǐng)求的信息為基礎(chǔ)創(chuàng)建出一個(gè) Laravel Request請(qǐng)求實(shí)例,在后續(xù)應(yīng)用剩余的生命周期中Request請(qǐng)求實(shí)例就是對(duì)本次HTTP請(qǐng)求的抽象,關(guān)于Laravel Request請(qǐng)求實(shí)例的講解可以參考以前的章節(jié)。

將HTTP請(qǐng)求抽象成Laravel Request請(qǐng)求實(shí)例后,請(qǐng)求實(shí)例會(huì)被傳導(dǎo)進(jìn)入到HTTP內(nèi)核的handle方法內(nèi)部,請(qǐng)求的處理就是由handle方法來(lái)完成的。

namespace IlluminateFoundationHttp;

class Kernel implements KernelContract
{
    /**
     * Handle an incoming HTTP request.
     *
     * @param  IlluminateHttpRequest  $request
     * @return IlluminateHttpResponse
     */
    public function handle($request)
    {
        try {
            $request->enableHttpMethodParameterOverride();

            $response = $this->sendRequestThroughRouter($request);
        } catch (Exception $e) {
            $this->reportException($e);

            $response = $this->renderException($request, $e);
        } catch (Throwable $e) {
            $this->reportException($e = new FatalThrowableError($e));

            $response = $this->renderException($request, $e);
        }

        $this->app["events"]->dispatch(
            new EventsRequestHandled($request, $response)
        );

        return $response;
    }
}

handle 方法接收一個(gè)請(qǐng)求對(duì)象,并最終生成一個(gè)響應(yīng)對(duì)象。其實(shí)handle方法我們已經(jīng)很熟悉了在講解很多模塊的時(shí)候都是以它為出發(fā)點(diǎn)逐步深入到模塊的內(nèi)部去講解模塊內(nèi)的邏輯的,其中sendRequestThroughRouter方法在服務(wù)提供者和中間件都提到過(guò),它會(huì)加載在內(nèi)核中定義的引導(dǎo)程序來(lái)引導(dǎo)啟動(dòng)應(yīng)用然后會(huì)將使用Pipeline對(duì)象傳輸HTTP請(qǐng)求對(duì)象流經(jīng)框架中定義的HTTP中間件們和路由中間件們來(lái)完成過(guò)濾請(qǐng)求最終將請(qǐng)求傳遞給處理程序(控制器方法或者路由中的閉包)由處理程序返回相應(yīng)的響應(yīng)。關(guān)于handle方法的注解我直接引用以前章節(jié)的講解放在這里,具體更詳細(xì)的分析具體是如何引導(dǎo)啟動(dòng)應(yīng)用以及如何將傳輸流經(jīng)各個(gè)中間件并到達(dá)處理程序的內(nèi)容請(qǐng)查看服務(wù)提供器、中間件還有路由這三個(gè)章節(jié)。

protected function sendRequestThroughRouter($request)
{
    $this->app->instance("request", $request);

    Facade::clearResolvedInstance("request");

    $this->bootstrap();

    return (new Pipeline($this->app))
                    ->send($request)
                    ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
                    ->then($this->dispatchToRouter());
}
    
/*引導(dǎo)啟動(dòng)Laravel應(yīng)用程序
1. DetectEnvironment  檢查環(huán)境
2. LoadConfiguration  加載應(yīng)用配置
3. ConfigureLogging   配置日至
4. HandleException    注冊(cè)異常處理的Handler
5. RegisterFacades    注冊(cè)Facades 
6. RegisterProviders  注冊(cè)Providers 
7. BootProviders      啟動(dòng)Providers
*/
public function bootstrap()
{
    if (! $this->app->hasBeenBootstrapped()) {
    /**依次執(zhí)行$bootstrappers中每一個(gè)bootstrapper的bootstrap()函數(shù)
        $bootstrappers = [
             "IlluminateFoundationBootstrapDetectEnvironment",
             "IlluminateFoundationBootstrapLoadConfiguration",
             "IlluminateFoundationBootstrapConfigureLogging",
             "IlluminateFoundationBootstrapHandleExceptions",
             "IlluminateFoundationBootstrapRegisterFacades",
             "IlluminateFoundationBootstrapRegisterProviders",
             "IlluminateFoundationBootstrapBootProviders",
            ];*/
            $this->app->bootstrapWith($this->bootstrappers());
    }
}
發(fā)送響應(yīng)

經(jīng)過(guò)上面的幾個(gè)階段后我們最終拿到了要返回的響應(yīng),接下來(lái)就是發(fā)送響應(yīng)了。

//public/index.php
$response = $kernel->handle(
    $request = IlluminateHttpRequest::capture()
);

// 發(fā)送響應(yīng)
$response->send();

發(fā)送響應(yīng)由 IlluminateHttpResponsesend()方法完成父類其定義在父類SymfonyComponentHttpFoundationResponse中。

public function send()
{
    $this->sendHeaders();// 發(fā)送響應(yīng)頭部信息
    $this->sendContent();// 發(fā)送報(bào)文主題

    if (function_exists("fastcgi_finish_request")) {
        fastcgi_finish_request();
    } elseif (!in_array(PHP_SAPI, array("cli", "phpdbg"), true)) {
        static::closeOutputBuffers(0, true);
    }
    return $this;
}

關(guān)于Response對(duì)象的詳細(xì)分析可以參看我們之前講解Laravel Response對(duì)象的章節(jié)。

終止應(yīng)用程序

響應(yīng)發(fā)送后,HTTP內(nèi)核會(huì)調(diào)用terminable中間件做一些后續(xù)的處理工作。比如,Laravel 內(nèi)置的「session」中間件會(huì)在響應(yīng)發(fā)送到瀏覽器之后將會(huì)話數(shù)據(jù)寫(xiě)入存儲(chǔ)器中。

// public/index.php
// 終止程序
$kernel->terminate($request, $response);
//IlluminateFoundationHttpKernel
public function terminate($request, $response)
{
    $this->terminateMiddleware($request, $response);
    $this->app->terminate();
}

// 終止中間件
protected function terminateMiddleware($request, $response)
{
    $middlewares = $this->app->shouldSkipMiddleware() ? [] : array_merge(
        $this->gatherRouteMiddleware($request),
        $this->middleware
    );
    foreach ($middlewares as $middleware) {
        if (! is_string($middleware)) {
            continue;
        }
        list($name, $parameters) = $this->parseMiddleware($middleware);
        $instance = $this->app->make($name);
        if (method_exists($instance, "terminate")) {
            $instance->terminate($request, $response);
        }
    }
}

Http內(nèi)核的terminate方法會(huì)調(diào)用teminable中間件的terminate方法,調(diào)用完成后從HTTP請(qǐng)求進(jìn)來(lái)到返回響應(yīng)整個(gè)應(yīng)用程序的生命周期就結(jié)束了。

總結(jié)

本節(jié)介紹的HTTP內(nèi)核起到的主要是串聯(lián)作用,其中設(shè)計(jì)到的初始化應(yīng)用、引導(dǎo)應(yīng)用、將HTTP請(qǐng)求抽象成Request對(duì)象、傳遞Request對(duì)象通過(guò)中間件到達(dá)處理程序生成響應(yīng)以及響應(yīng)發(fā)送給客戶端。這些東西在之前的章節(jié)里都有講過(guò),并沒(méi)有什么新的東西,希望通過(guò)這篇文章能讓大家把之前文章里講到的每個(gè)點(diǎn)串成一條線,這樣對(duì)Laravel整體是怎么工作的會(huì)有更清晰的概念。

本文已經(jīng)收錄在系列文章Laravel源碼學(xué)習(xí)里。

也歡迎關(guān)注我的公眾號(hào) 網(wǎng)管叨bi叨 ,最近正在籌備準(zhǔn)備分享一些日常工作里學(xué)到和總結(jié)的技術(shù)知識(shí),也會(huì)分享一些見(jiàn)聞和學(xué)習(xí)英語(yǔ)的方法。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/29622.html

相關(guān)文章

  • Laravel核心解讀--Console內(nèi)核

    摘要:其中設(shè)置請(qǐng)求是唯一區(qū)別于內(nèi)核的一個(gè)引導(dǎo)程序。和命令行腳本的規(guī)范一樣,如果執(zhí)行命令任務(wù)程序成功會(huì)返回拋出異常退出則返回。嚴(yán)格遵循了面向?qū)ο蟪绦蛟O(shè)計(jì)的原則。 Console內(nèi)核 上一篇文章我們介紹了Laravel的HTTP內(nèi)核,詳細(xì)概述了網(wǎng)絡(luò)請(qǐng)求從進(jìn)入應(yīng)用到應(yīng)用處理完請(qǐng)求返回HTTP響應(yīng)整個(gè)生命周期中HTTP內(nèi)核是如何調(diào)動(dòng)Laravel各個(gè)核心組件來(lái)完成任務(wù)的。除了處理HTTP請(qǐng)求一個(gè)健壯...

    Barry_Ng 評(píng)論0 收藏0
  • Laravel核心解讀--完結(jié)篇

    摘要:過(guò)去一年時(shí)間寫(xiě)了多篇文章來(lái)探討了我認(rèn)為的框架最核心部分的設(shè)計(jì)思路代碼實(shí)現(xiàn)。為了大家閱讀方便,我把這些源碼學(xué)習(xí)的文章匯總到這里。數(shù)據(jù)庫(kù)算法和數(shù)據(jù)結(jié)構(gòu)這些都是編程的內(nèi)功,只有內(nèi)功深厚了才能解決遇到的復(fù)雜問(wèn)題。 過(guò)去一年時(shí)間寫(xiě)了20多篇文章來(lái)探討了我認(rèn)為的Larave框架最核心部分的設(shè)計(jì)思路、代碼實(shí)現(xiàn)。通過(guò)更新文章自己在軟件設(shè)計(jì)、文字表達(dá)方面都有所提高,在剛開(kāi)始決定寫(xiě)Laravel源碼分析地...

    laoLiueizo 評(píng)論0 收藏0
  • Laravel核心解讀--Contracts契約

    摘要:的契約是一組定義框架提供的核心服務(wù)的接口,例如我們?cè)诮榻B用戶認(rèn)證的章節(jié)中到的用戶看守器契約和用戶提供器契約以及框架自帶的模型所實(shí)現(xiàn)的契約。接口與團(tuán)隊(duì)開(kāi)發(fā)當(dāng)你的團(tuán)隊(duì)在開(kāi)發(fā)大型應(yīng)用時(shí),不同的部分有著不同的開(kāi)發(fā)速度。 Contracts Laravel 的契約是一組定義框架提供的核心服務(wù)的接口, 例如我們?cè)诮榻B用戶認(rèn)證的章節(jié)中到的用戶看守器契約IllumninateContractsAuth...

    Prasanta 評(píng)論0 收藏0
  • Laravel核心解讀 -- Response

    摘要:設(shè)置生成對(duì)象后就要執(zhí)行對(duì)象的方法了,該方法定義在類中,其主要目的是對(duì)進(jìn)行微調(diào)使其能夠遵從協(xié)議。最后會(huì)把完整的響應(yīng)發(fā)送給客戶端。本文已經(jīng)收錄在系列文章源碼學(xué)習(xí)里,歡迎訪問(wèn)閱讀。 Response 前面兩節(jié)我們分別講了Laravel的控制器和Request對(duì)象,在講Request對(duì)象的那一節(jié)我們看了Request對(duì)象是如何被創(chuàng)建出來(lái)的以及它支持的方法都定義在哪里,講控制器時(shí)我們?cè)敿?xì)地描述了...

    TigerChain 評(píng)論0 收藏0
  • Laravel核心解讀 -- Request

    摘要:根據(jù)提供的超級(jí)全局?jǐn)?shù)組來(lái)創(chuàng)建實(shí)例上面的代碼有一處需要額外解釋一下,自開(kāi)始內(nèi)建的可以通過(guò)命令行解釋器來(lái)啟動(dòng),例如但是內(nèi)建有一個(gè)是將和這兩個(gè)請(qǐng)求首部存儲(chǔ)到了和中,為了統(tǒng)一內(nèi)建服務(wù)器和真正的中的請(qǐng)求首部字段所以在這里做了特殊處理。 Request 很多框架都會(huì)將來(lái)自客戶端的請(qǐng)求抽象成類方便應(yīng)用程序使用,在Laravel中也不例外。IlluminateHttpRequest類在Laravel框...

    K_B_Z 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<