- index.php,判断维护模式,
- require composer的自动加载文件,
- require app.php(实例化APP容器,单例绑定kernel),
- 解析http kernel,执行$kernel->handlle($request)->send();
- 最后执行$kernel->terminate($request, $response);
HTTP / Console 内核
- 其中$kernel->handlle中,sendRequestThroughRouter方法
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());
}
- HTTP 内核定义了$bootstrappers,这些引导程序用来配置异常处理、配置日志、检测应用程序环境
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,
];
- HTTP 内核还定义了一个 HTTP 中间件列表,所有请求在被应用程序处理之前都必须通过该列表。这些中间件处理读写 HTTP 会话 ,确定应用程序是否处于维护模式, 校验 CSRF 令牌 , 等等。
路由
路由器 <-> 中间件 <-> 路由或控制器
应用程序中最重要的服务提供者之一是 App\Providers\RouteServiceProvider。
一旦应用程序被引导并且所有服务提供者都被注册,Request 将被传递给路由器进行调度。路由器将请求发送到路由或控制器,并运行任何路由特定的中间件。
protected function sendRequestThroughRouter($request)
{
$this->app->instance('request', $request);
Facade::clearResolvedInstance('request');
$this->bootstrap();
//这个pipeline像onion一样层层叠叠,array_reduce
return (new Pipeline($this->app))
->send($request)
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
->then($this->dispatchToRouter());
}
一些中间件被分配给应用程序中的所有路由,比如那些在HTTP 内核的 $middleware 属性中定义的路由,而一些只被分配给特定的路由或路由组。
如果请求通过了所有匹配路由分配的中间件,则执行路由或控制器方法,并通过路由的中间件链路返回路由或控制器方法的响应。
protected function runRouteWithinStack(Route $route, Request $request)
{
$shouldSkipMiddleware = $this->container->bound('middleware.disable') &&
$this->container->make('middleware.disable') === true;
$middleware = $shouldSkipMiddleware ? [] : $this->gatherRouteMiddleware($route);
return (new Pipeline($this->container))
->send($request)
->through($middleware)
->then(fn ($request) => $this->prepareResponse(
$request, $route->run()
));
}
最后
一旦路由或控制器方法返回一个响应,该响应将通过路由的中间件返回,从而使应用程序有机会修改或检查传出的响应。
最后,一旦响应通过中间件返回,HTTP 内核的 handle 方法将返回响应对象,并且 index.php 文件在返回的响应上调用 send 方法。send 方法将响应内容发送到用户的 Web 浏览器。至此,我们已经完成了整个 Laravel 请求生命周期的旅程!
最最后,如果你在中间件上定义了一个 terminate 方法,并且你的 Web 服务器使用 FastCGI,则在将响应发送到浏览器后会自动调用 terminate 方法。