本文目录导读:

- 第一阶段:请求入口(Public/index.php)
- 第二阶段:HTTP 内核引导(Kernel Bootstrap)
- 第三阶段:全局中间件与路由分发
- 第四阶段:控制器与业务逻辑(核心)
- 第五阶段:响应返回与终止
- 生命周期流程图
Laravel 的生命周期是理解框架核心的关键,当你通过浏览器访问一个 Laravel 应用时,代码的执行遵循一个严格的顺序。
以下是 Laravel 生命周期的完整执行顺序,分为 “请求入口”、“内核引导”、“服务容器与中间件” 和 “应用处理” 四个阶段。
第一阶段:请求入口(Public/index.php)
这是所有 HTTP 请求的起点。
- Web 服务器(Nginx/Apache) 接收请求,并将所有符合条件的请求重定向到
public/index.php文件。 index.php执行两件事:- 加载 Composer 自动加载器:
require __DIR__.'/../vendor/autoload.php';,这会将所有第三方依赖和项目自身的类自动加载进来。 - 启动内核:
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);$response = $kernel->handle($request = Request::capture());,这里的$app是应用容器(Application),是整个 Laravel 的心脏。
- 加载 Composer 自动加载器:
第二阶段:HTTP 内核引导(Kernel Bootstrap)
请求已经传递给了 app/Http/Kernel.php,内核负责定义服务提供者和中间件,并引导应用启动。
Kernel::handle()执行核心逻辑,这里有两个步骤:bootstrap():将app/Http/Kernel.php中的$bootstrappers数组按顺序执行,这包括:LoadEnvironmentVariables:加载.env文件。LoadConfiguration:加载config/目录所有配置文件。HandleExceptions:注册异常处理器(Whoops)。RegisterFacades:注册门面(Facades)。RegisterProviders:注册所有基础服务提供者(基础 Service Providers)。BootProviders:调用所有服务提供者的boot()方法。
- **这一步之后,框架内部的依赖关系已完全建立,数据库、日志、验证器、路由等组件都已准备就绪。 **
sendRequestThroughRouter():将请求交给路由管道(Pipeline)。
第三阶段:全局中间件与路由分发
- 全局中间件:请求首先会通过
app/Http/Kernel.php中$middleware属性定义的全局中间件(CheckForMaintenanceMode维护模式、ValidatePostSize等)。 - 路由匹配(Routing):请求通过全局中间件后,进入路由分发器。
RouteServiceProvider会加载routes/web.php或routes/api.php。 - 路由中间件:匹配到路由后,该路由定义的中间件组或单个中间件(如
auth、admin)会被添加到请求路径中,再次通过 Pipeline 挂载。
关键在于: 中间件不是一次性全部执行的,它们是嵌套的,请求会一层层穿过中间件,到达核心控制器,返回时再一层层穿出。
第四阶段:控制器与业务逻辑(核心)
- 依赖注入:控制器通过反射自动解析构造函数或方法中的类型提示(Type-Hint)参数,如果没有则从容器中实例化。
- 执行控制器方法:执行控制器中的业务逻辑(如数据库操作、调用服务类、查询日志等)。
- 渲染视图:如果控制器返回
view('welcome'),View 组件会编译 Blade 模板,并返回Response对象。 - 返回响应:控制器返回的数据或视图最终被包装成
Illuminate\Http\Response对象,并返回给路由管道。
第五阶段:响应返回与终止
- 响应回传:
Response对象沿着中间件管道反向层层穿出(执行中间件的$next之后的代码,如果有的话)。 - 发送响应:
Kernel::handle()返回$response,index.php执行$response->send();将 HTTP 头信息和内容发送到浏览器。 - 终止回调(
terminate):- 输出发送完毕后,
index.php调用$kernel->terminate($request, $response);。 - Laravel 会执行注册了
terminate方法的中间件(如果写了),用于清理缓存、关闭数据库连接等操作。 - PHP 代码执行完毕,脚本结束。
- 输出发送完毕后,
生命周期流程图
浏览器请求 | v URL 重写 -> public/index.php | v 加载 Composer Autoload => $app(服务容器) | v 请求 -> Kernel::handle() | v Bootstrap()(加载env、配置、门面、服务提供者) | v 进入中间件管道 (Pipeline) +------+------+------+------+------+ | G1 | G2 | Route | A1 | A2 | +------+------+------+------+------+ | | v v 路由匹配 (Router) 执行控制器逻辑 ----------> 返回 Response | | +------ 响应反向穿出中间件 --------------+ | v 发送 Response 给客户端 | v Kernel::terminate() (清理资源) | v 脚本结束
- 门面(Facade)的原理:在
Bootstrap()中的RegisterFacades阶段,门面代理已经绑定到容器,因此你可以直接通过\DB::table()调用,而无需手动use实例。 - 中间件顺序:中间件遵循洋葱模型,层级的顺序决定了你的控制器是在哪里被执行的,全局中间件 > 路由组中间件 > 单路由中间件。
- 为什么这么设计:这种生命周期让 HTTP 请求被解耦,你可以在任意一层插入逻辑(权限验证、日志记录、跨域处理等),而控制器本身只需要关注业务逻辑。
如果你是在开发中遇到“某段代码在哪执行”,通常可以按这个逻辑去排查:是先走了 middleware,还是先执行了 controller? 这取决于它注册的位置。