Cet article vous apporte une analyse détaillée du noyau HTTP dans Laravel. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il vous sera utile.
Http Kernel
Http Kernel est utilisé dans Laravel pour connecter les composants principaux du framework afin d'effectuer des requêtes réseau. En termes simples, démarrez simplement le framework via public/index.php
. Tous utiliseront le noyau Http, et d'autres qui sont traités via la commande artisan
, les tâches planifiées et le cadre de démarrage de la file d'attente utiliseront le noyau de la console. Aujourd'hui, nous allons d'abord comprendre ce que fait le noyau Http.
Étant donné que le noyau Http est utilisé dans Laravel pour connecter diverses parties du framework afin de traiter les requêtes réseau, examinons comment le noyau est chargé dans l'instance d'application dans Laravel. Dans public/index.php, nous verrons que l'application sera d'abord initialisée via le fichier d'échafaudage bootstrap/app.php :
Ce qui suit est le code de bootstrap/app.php, qui contient deux parties principales pour créer une instance d'application et lier le noyau au conteneur de service APP
<?php // 第一部分: 创建应用实例 $app = new Illuminate\Foundation\Application( realpath(__DIR__.'/../') ); // 第二部分: 完成内核绑定 $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;
Le noyau HTTP hérite de la classe IlluminateFoundationHttpKernel, qui définit un tableau lié au middleware dans le noyau HTTP. Le middleware fournit un mécanisme pratique pour filtrer les requêtes HTTP. entrant dans l’application et traitant les réponses HTTP sortant de l’application.
<?php namespace App\Http; use Illuminate\Foundation\Http\Kernel as HttpKernel; class Kernel extends HttpKernel { /** * The application'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's route middleware groups. * * @var array */ protected $middlewareGroups = [ 'web' => [ \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, ]; }
Dans sa classe parent "IlluminateFoundationHttpKernel", un tableau d'amorçage avec le nom d'attribut "bootstrappers" est défini :
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, ];
Le groupe d'amorçage inclut l'achèvement de la détection et de la configuration de l'environnement le chargement, la gestion des exceptions, l'enregistrement des façades, l'enregistrement du fournisseur de services et le démarrage des services sont les six procédures d'amorçage.
Après avoir lié le noyau Http au conteneur de service de l'application pendant la phase d'initialisation de l'application, nous pouvons voir l'utilisation du conteneur de service dans public/index.php La méthode make analyse sur l'instance du noyau HTTP :
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
Lors de l'instanciation du noyau, le middleware défini dans le noyau HTTP est enregistré sur le routeur. Après enregistrement, il peut être appelé avant de traiter réellement la requête HTTP appliquée. sur la route implémente l'objectif de filtrer les requêtes :
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; } }
Après avoir terminé la création de l'instance principale HTTP via la résolution de service, vous pouvez utiliser l'instance principale HTTP pour traiter Requêtes HTTP.
//public/index.php $response = $kernel->handle( $request = Illuminate\Http\Request::capture() );
Avant de traiter la requête, une instance de requête Laravel Request sera créée sur la base des informations de la requête HTTP entrant dans l'application via la méthode capture() de la requête IlluminateHttpRequest. le cycle de vie restant de l'application. L'instance de requête est l'abstraction de cette requête HTTP
Après avoir abstrait la requête HTTP dans une instance de requête Laravel Request, l'instance de requête sera transmise dans la méthode handle du noyau HTTP. , et le traitement de la demande est terminé par la méthode handle de. La méthode
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 reçoit un objet de requête et génère finalement un objet de réponse. En fait, nous connaissons déjà très bien la méthode handle lorsque nous expliquons de nombreux modules, nous l'utilisons comme point de départ et approfondissons progressivement le module pour expliquer la logique au sein du module. Parmi elles, la méthode sendRequestThroughRouter a été mentionnée dans. à la fois les fournisseurs de services et le middleware. Le programme de démarrage défini dans le noyau sera chargé pour démarrer l'application, puis l'objet Pipeline sera utilisé pour transmettre l'objet de requête HTTP et passer par le middleware HTTP et le middleware de routage définis dans le framework pour terminer le middleware HTTP. filtrage de la requête et enfin transmettre la requête au gestionnaire (une méthode de contrôleur ou une fermeture dans une route) avec la réponse correspondante renvoyée par le gestionnaire.
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()); } }
Après avoir parcouru les étapes ci-dessus, nous obtenons enfin que la réponse soit renvoyée, et l'étape suivante consiste à envoyer la réponse.
//public/index.php $response = $kernel->handle( $request = Illuminate\Http\Request::capture() ); // 发送响应 $response->send();
l'envoi d'une réponse est complété par la méthode IlluminateHttpResponse
de la classe parent qui est définie dans la classe parent send()
. 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; }Pour une analyse détaillée de l'objet Response, veuillez vous référer à notre chapitre précédent expliquant l'objet Response Laravel. Terminer l'applicationUne fois la réponse envoyée, le noyau HTTP appellera le
middleware pour effectuer un traitement ultérieur. Par exemple, le middleware « session » intégré de Laravel écrit les données de session dans le stockage une fois la réponse envoyée au navigateur. terminable
// public/index.php // 终止程序 $kernel->terminate($request, $response);
//Illuminate\Foundation\Http\Kernel 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); } } }La méthode
du noyau HTTP appellera la méthode terminate
du middleware teminable
Une fois l'appel terminé, tout le cycle de vie de l'application, depuis la requête HTTP jusqu'à la réponse de retour, se termine. . terminate
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!