PHP项目Laravel生命周期执行顺序

wen PHP项目 9

本文目录导读:

PHP项目Laravel生命周期执行顺序

  1. 第一阶段:请求入口(Public/index.php)
  2. 第二阶段:HTTP 内核引导(Kernel Bootstrap)
  3. 第三阶段:全局中间件与路由分发
  4. 第四阶段:控制器与业务逻辑(核心)
  5. 第五阶段:响应返回与终止
  6. 生命周期流程图

Laravel 的生命周期是理解框架核心的关键,当你通过浏览器访问一个 Laravel 应用时,代码的执行遵循一个严格的顺序。

以下是 Laravel 生命周期的完整执行顺序,分为 “请求入口”“内核引导”“服务容器与中间件”“应用处理” 四个阶段。


第一阶段:请求入口(Public/index.php)

这是所有 HTTP 请求的起点。

  1. Web 服务器(Nginx/Apache) 接收请求,并将所有符合条件的请求重定向到 public/index.php 文件。
  2. 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 的心脏。

第二阶段:HTTP 内核引导(Kernel Bootstrap)

请求已经传递给了 app/Http/Kernel.php,内核负责定义服务提供者和中间件,并引导应用启动。

  1. Kernel::handle() 执行核心逻辑,这里有两个步骤:
    • bootstrap():将 app/Http/Kernel.php 中的 $bootstrappers 数组按顺序执行,这包括:
      • LoadEnvironmentVariables:加载 .env 文件。
      • LoadConfiguration:加载 config/ 目录所有配置文件。
      • HandleExceptions:注册异常处理器(Whoops)。
      • RegisterFacades:注册门面(Facades)。
      • RegisterProviders:注册所有基础服务提供者(基础 Service Providers)。
      • BootProviders:调用所有服务提供者的 boot() 方法。
    • **这一步之后,框架内部的依赖关系已完全建立,数据库、日志、验证器、路由等组件都已准备就绪。 **
    • sendRequestThroughRouter():将请求交给路由管道(Pipeline)

第三阶段:全局中间件与路由分发

  1. 全局中间件:请求首先会通过 app/Http/Kernel.php$middleware 属性定义的全局中间件CheckForMaintenanceMode 维护模式、ValidatePostSize 等)。
  2. 路由匹配(Routing):请求通过全局中间件后,进入路由分发器。RouteServiceProvider 会加载 routes/web.phproutes/api.php
  3. 路由中间件:匹配到路由后,该路由定义的中间件组单个中间件(如 authadmin)会被添加到请求路径中,再次通过 Pipeline 挂载。

关键在于: 中间件不是一次性全部执行的,它们是嵌套的,请求会一层层穿过中间件,到达核心控制器,返回时再一层层穿出。


第四阶段:控制器与业务逻辑(核心)

  1. 依赖注入:控制器通过反射自动解析构造函数或方法中的类型提示(Type-Hint)参数,如果没有则从容器中实例化。
  2. 执行控制器方法:执行控制器中的业务逻辑(如数据库操作、调用服务类、查询日志等)。
  3. 渲染视图:如果控制器返回 view('welcome'),View 组件会编译 Blade 模板,并返回 Response 对象。
  4. 返回响应:控制器返回的数据或视图最终被包装成 Illuminate\Http\Response 对象,并返回给路由管道

第五阶段:响应返回与终止

  1. 响应回传Response 对象沿着中间件管道反向层层穿出(执行中间件的 $next 之后的代码,如果有的话)。
  2. 发送响应Kernel::handle() 返回 $responseindex.php 执行 $response->send(); 将 HTTP 头信息和内容发送到浏览器。
  3. 终止回调(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 这取决于它注册的位置。

抱歉,评论功能暂时关闭!