Heim  >  Artikel  >  PHP-Framework  >  Detaillierte Analyse des HTTP-Kernels in Laravel

Detaillierte Analyse des HTTP-Kernels in Laravel

不言
不言nach vorne
2018-11-12 14:06:384111Durchsuche

Dieser Artikel bietet Ihnen eine detaillierte Analyse des HTTP-Kerns in Laravel. Freunde in Not können darauf zurückgreifen.

Http-Kernel

Http-Kernel wird in Laravel verwendet, um die Kernkomponenten des Frameworks zu verbinden, um Netzwerkanfragen zu stellen. Starten Sie das Framework einfach über public/index.php Alle verwenden den HTTP-Kernel, und andere, die über den Befehl artisan, geplante Aufgaben und das Warteschlangenstart-Framework verarbeitet werden, verwenden den Konsolenkern. Heute werden wir zunächst herausfinden, was der HTTP-Kernel tut.

Kernel-Bindung

Da der HTTP-Kernel in Laravel verwendet wird, um verschiedene Teile des Frameworks zu verbinden, um Netzwerkanfragen zu verarbeiten, werfen wir einen Blick darauf, wie der Kernel in die Anwendungsinstanz in Laravel geladen wird. In public/index.php sehen wir, dass die Anwendung zunächst über die Gerüstdatei bootstrap/app.php initialisiert wird:

Das Folgende ist der Code für bootstrap/app.php, der zwei Hauptteile enthält Erstellen Sie eine Anwendungsinstanz und binden Sie den Kernel an den APP-Dienstcontainer.

<?php
// 第一部分: 创建应用实例
$app = new Illuminate\Foundation\Application(
    realpath(__DIR__.&#39;/../&#39;)
);

// 第二部分: 完成内核绑定
$app->singleton(
    Illuminate\Contracts\Http\Kernel::class,
    App\Http\Kernel::class
);

$app->singleton(
    Illuminate\Contracts\Console\Kernel::class,
    App\Console\Kernel::class
);

$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::class
);

return $app;

Der HTTP-Kernel erbt von der IlluminateFoundationHttpKernel-Klasse, die ein Middleware-bezogenes Array im HTTP-Kernel definiert. Middleware bietet einen praktischen Mechanismus zum Filtern eingehender HTTP-Anforderungen von Anwendungen und Verarbeitung von HTTP-Antworten aus der Anwendung heraus.

<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
    /**
     * The application&#39;s global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        \App\Http\Middleware\TrustProxies::class,
    ];
    /**
     * The application&#39;s route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        &#39;web&#39; => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];
    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used inpidually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    ];
}

definiert ein Bootstrap-Array mit dem Attributnamen „bootstrappers“ innerhalb seiner übergeordneten Klasse „IlluminateFoundationHttpKernel“:

protected $bootstrappers = [
    \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
    \Illuminate\Foundation\Bootstrap\LoadConfiguration::class,
    \Illuminate\Foundation\Bootstrap\HandleExceptions::class,
    \Illuminate\Foundation\Bootstrap\RegisterFacades::class,
    \Illuminate\Foundation\Bootstrap\RegisterProviders::class,
    \Illuminate\Foundation\Bootstrap\BootProviders::class,
];

Die Bootstrap-Gruppe umfasst den Abschluss der Umgebungserkennung, das Laden der Konfiguration, die Ausnahmebehandlung und die Fassadenregistrierung , Dienstanbieterregistrierung und Dienststart sind die sechs Bootstrapping-Verfahren.

Anwendungs-Parsing-Kernel

Nachdem wir den HTTP-Kernel während der Anwendungsinitialisierungsphase an den Dienstcontainer der Anwendung gebunden haben, können wir die Verwendung des Dienstcontainers in public/index.php sehen. Die Make-Methode wird analysiert aus der HTTP-Kernel-Instanz:

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

Beim Instanziieren des Kernels wird die im HTTP-Kernel definierte Middleware beim Router registriert. Nach der Registrierung kann die Route aufgerufen werden, bevor die HTTP-Anfrage tatsächlich implementiert wird Der Zweck des Filterns von Anfragen:

namespace Illuminate\Foundation\Http;
...
class Kernel implements KernelContract
{
    /**
     * Create a new HTTP kernel instance.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @param  \Illuminate\Routing\Router  $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;
    }
}

Verarbeiten von HTTP-Anfragen

Nach Abschluss der Erstellung der HTTP-Kerninstanz durch Dienstauflösung können Sie die HTTP-Kerninstanz zum Verarbeiten von HTTP-Anfragen verwenden

//public/index.php
$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

Bevor die Anfrage verarbeitet wird, wird zunächst eine Laravel-Request-Anfrageinstanz erstellt, die auf den Informationen der HTTP-Anfrage basiert, die über die Capture()-Methode von IlluminateHttpRequest in die Anwendung eingegeben wird. Im verbleibenden Lebenszyklus der nachfolgenden Anwendung wird die Anfrage angefordert Die Instanz wird die Antwort auf diese Anfrage sein.

Nach der Abstraktion der HTTP-Anfrage in eine Laravel-Request-Anfrageinstanz wird die Anfrageinstanz in die Handle-Methode des HTTP-Kernels übertragen und die Anfrage verarbeitet wird durch die Handle-Methode vervollständigt. Die

namespace Illuminate\Foundation\Http;

class Kernel implements KernelContract
{
    /**
     * Handle an incoming HTTP request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    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 Events\RequestHandled($request, $response)
        );
        return $response;
    }
}

handle-Methode empfängt ein Anforderungsobjekt und generiert letztendlich ein Antwortobjekt. Tatsächlich sind wir mit der Handle-Methode bereits sehr vertraut. Bei der Erläuterung vieler Module verwenden wir sie als Ausgangspunkt, um schrittweise tiefer in das Modul einzusteigen und die Logik innerhalb des Moduls zu erklären Sowohl Dienstanbieter als auch Middleware werden geladen, um die Anwendung zu starten. Anschließend wird das Pipeline-Objekt verwendet, um das HTTP-Anforderungsobjekt zu übertragen und zum Abschluss durch die im Framework definierte HTTP-Middleware und Routing-Middleware zu fließen Filtern Sie die Anfrage und übergeben Sie sie schließlich an den Handler (eine Controller-Methode oder einen Abschluss in einer Route), wobei die entsprechende Antwort vom Handler zurückgegeben wird.

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());
}
    
/*引导启动Laravel应用程序
1. DetectEnvironment  检查环境
2. LoadConfiguration  加载应用配置
3. ConfigureLogging   配置日至
4. HandleException    注册异常处理的Handler
5. RegisterFacades    注册Facades 
6. RegisterProviders  注册Providers 
7. BootProviders      启动Providers
*/
public function bootstrap()
{
    if (! $this->app->hasBeenBootstrapped()) {
    /**依次执行$bootstrappers中每一个bootstrapper的bootstrap()函数
        $bootstrappers = [
             'Illuminate\Foundation\Bootstrap\DetectEnvironment',
             'Illuminate\Foundation\Bootstrap\LoadConfiguration',
             'Illuminate\Foundation\Bootstrap\ConfigureLogging',
             'Illuminate\Foundation\Bootstrap\HandleExceptions',
             'Illuminate\Foundation\Bootstrap\RegisterFacades',
             'Illuminate\Foundation\Bootstrap\RegisterProviders',
             'Illuminate\Foundation\Bootstrap\BootProviders',
            ];*/
            $this->app->bootstrapWith($this->bootstrappers());
    }
}

Antwort senden

Nachdem wir die oben genannten Phasen durchlaufen haben, erhalten wir endlich die Antwort, die zurückgegeben werden soll, und der nächste Schritt besteht darin, die Antwort zu senden.

//public/index.php
$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

// 发送响应
$response->send();

sendet eine Antwort durch die IlluminateHttpResponse-Methode der übergeordneten Klasse, die in der übergeordneten Klasse send() definiert ist. SymfonyComponentHttpFoundationResponse

public function send()
{
    $this->sendHeaders();// 发送响应头部信息
    $this->sendContent();// 发送报文主题

    if (function_exists('fastcgi_finish_request')) {
        fastcgi_finish_request();
    } elseif (!\in_array(PHP_SAPI, array('cli', 'phpdbg'), true)) {
        static::closeOutputBuffers(0, true);
    }
    return $this;
}
Eine detaillierte Analyse des Response-Objekts finden Sie in unserem vorherigen Kapitel, in dem das Laravel Response-Objekt erläutert wird.

Beenden Sie die Anwendung

Nachdem die Antwort gesendet wurde, ruft der HTTP-Kernel die

Middleware auf, um eine nachfolgende Verarbeitung durchzuführen. Beispielsweise schreibt die integrierte „Session“-Middleware von Laravel Sitzungsdaten in den Speicher, nachdem die Antwort an den Browser gesendet wurde. terminable

// public/index.php
// 终止程序
$kernel->terminate($request, $response);
rrreeDie

-Methode des HTTP-Kernels ruft die terminate-Methode der teminable-Middleware auf. Nach Abschluss des Aufrufs ist der gesamte Anwendungslebenszyklus von der HTTP-Anfrage bis zur Rückantwort abgeschlossen über. terminate

Zusammenfassung

Der in diesem Abschnitt vorgestellte HTTP-Kernel spielt hauptsächlich eine Serienrolle. Er dient dazu, Anwendungen zu initialisieren, Anwendungen zu leiten, HTTP-Anforderungen in Anforderungsobjekte zu abstrahieren und Anforderungsobjekte durch die Mitte zu leiten Der Dateiankunftshandler generiert eine Antwort und die Antwort wird an den Client gesendet.

Das obige ist der detaillierte Inhalt vonDetaillierte Analyse des HTTP-Kernels in Laravel. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen