> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# 请求生命周期

> 介绍 Laravel 应用如何处理 HTTP 请求以及 Console 命令。

## 简介

在「真实世界」中使用工具时，如果你了解它的工作原理，就能更自信地使用。开发应用也是同理。当你理解开发工具的运作方式后，就能更从容、更有信心地构建应用。

本页将从高层次介绍 Laravel 框架的工作原理。全面理解整个框架，可以让一切不再显得像「魔法」，从而增强你构建应用的信心。

## HTTP 请求生命周期

### 整体流程

```mermaid theme={null}
flowchart TD
    A[浏览器/HTTP 请求] --> B[public/index.php]
    B --> C[加载 Composer 自动加载器]
    C --> D[bootstrap/app.php]
    D --> E[创建应用实例<br>服务容器]
    E --> F[HTTP 内核]
    F --> G[执行引导程序<br>错误处理/日志/环境检测]
    G --> H[注册并启动服务提供者<br>register → boot]
    H --> I[通过中间件栈]
    I --> J[路由]
    J --> K[执行控制器/闭包]
    K --> L[生成响应]
    L --> I
    I --> M[向浏览器发送响应]
```

### 起始步骤

Laravel 应用所有请求的入口是 `public/index.php` 文件。所有请求都会被 Web 服务器（Apache / Nginx）的配置转发到该文件。`index.php` 本身几乎没有代码，只是加载框架其余部分的起点。

`index.php` 加载 Composer 生成的自动加载器定义，并从 `bootstrap/app.php` 获取 Laravel 应用实例。Laravel 首先完成的工作是创建应用/[服务容器](/zh/service-container)实例。

### HTTP 内核

接着，请求会交给 HTTP 内核（`Illuminate\Foundation\Http\Kernel`）处理。通过应用实例的 `handleRequest` 方法进行处理。

HTTP 内核定义了在请求执行前先执行的**引导程序**（bootstrappers）数组。这些引导程序会执行以下工作：

* 配置错误处理
* 配置日志
* [检测应用环境](/zh/installation)
* 其他在请求处理前所需的任务

HTTP 内核还负责让请求通过应用的中间件栈。这些中间件会处理 [HTTP Session](/zh/session)的读写、判断应用是否处于维护模式、[校验 CSRF 令牌](/zh/middleware)等。

HTTP 内核 `handle` 方法的签名很简单：接收 `Request`，返回 `Response`。可以把它想象成代表整个应用的一个大黑盒——把 HTTP 请求扔进去，就会得到 HTTP 响应。

### 服务提供者

内核在引导过程中最重要的工作之一是加载应用的[服务提供者](/zh/service-providers)。服务提供者负责引导数据库、队列、校验、路由等框架的各个组件。

Laravel 会遍历提供者列表，并逐一实例化。实例化完成后，会调用所有提供者的 `register` 方法。之后，当所有提供者都注册完毕，再依次调用它们的 `boot` 方法。这样一来，`boot` 方法执行时，所有容器绑定都已经就绪可用。

<Info>
  用户自定义或第三方服务提供者需要在 `bootstrap/providers.php` 文件中注册。
</Info>

### 路由

应用完成引导且所有服务提供者注册好后，`Request` 就会被交给路由器进行调度。路由器把请求派发到路由或控制器，并执行路由特定的中间件。

中间件为过滤或检查进入应用的 HTTP 请求提供了一种便利机制。例如，Laravel 内置了判断用户是否已认证的中间件。若用户未认证，该中间件会重定向到登录页面；若已认证，则允许请求继续进入应用内部。

请求通过所有匹配到的路由所对应的中间件后，路由或控制器方法就会执行并返回响应。

### 返回响应

当路由或控制器方法返回响应后，响应又会经过路由中间件从内向外传递，为应用提供在响应发出前进行修改或检查的机会。

最终响应通过所有中间件后，HTTP 内核 `handle` 方法会将响应对象返回给应用实例的 `handleRequest`，该方法再调用响应的 `send` 方法。`send` 方法把响应内容发送到用户的浏览器。至此，Laravel 请求生命周期的整个旅程就完成了。

## Console 命令生命周期

### 整体流程

```mermaid theme={null}
flowchart TD
    A[执行 artisan 命令] --> B[artisan]
    B --> C[加载 Composer 自动加载器]
    C --> D[bootstrap/app.php]
    D --> E[创建应用实例<br>服务容器]
    E --> F[控制台内核<br>handleCommand]
    F --> G[注册并启动服务提供者<br>register → boot]
    G --> H[加载命令<br>app/Console/Commands]
    H --> I[执行命令]
    I --> J[返回退出码]
```

### artisan 入口

控制台命令的入口是项目根目录的 `artisan` 文件。与 HTTP 请求类似，它同样会加载 Composer 的自动加载器并创建 Laravel 应用实例。

接着，处理会通过应用实例的 `handleCommand` 方法交给控制台内核。

### 控制台内核与命令执行

控制台内核和 HTTP 内核一样，也会加载服务提供者。当所有提供者被注册并启动后，Laravel 会加载 `app/Console/Commands` 目录中的命令并执行你指定的命令。

```shell theme={null}
php artisan make:controller UserController
```

该命令的处理流程如下：

1. `artisan` 加载 Composer 自动加载器
2. 从 `bootstrap/app.php` 创建应用实例
3. 控制台内核加载服务提供者
4. 查找并执行 `make:controller` 命令
5. 返回退出码

## 关注服务提供者

服务提供者是引导 Laravel 应用的真正关键。应用实例创建、服务提供者注册、请求交给已引导的应用——仅此而已。

深入理解 Laravel 应用如何借助服务提供者被构建与启动是非常有价值的。用户自定义的服务提供者保存在应用的 `app/Providers` 目录下。

<Info>
  默认的 `AppServiceProvider` 几乎是空的。它非常适合放入应用自身的引导逻辑与服务容器绑定。在大型应用中，我们建议按不同服务将启动逻辑拆分为多个服务提供者。
</Info>

### register 与 boot 的区别

服务提供者有两个主要方法。

| 方法         | 调用时机                    | 用途                       |
| ---------- | ----------------------- | ------------------------ |
| `register` | 所有提供者实例化后，全部依次调用        | 仅用于向服务容器注册绑定             |
| `boot`     | 所有提供者的 `register` 完成后调用 | 视图 Composer、事件监听器以及其他初始化 |

<Warning>
  不要在 `register` 方法中注册事件监听器、路由或其他功能。这可能会不小心使用了尚未加载的服务提供者所提供的服务。
</Warning>

## 下一步

<Card title="服务容器" icon="box" href="/zh/service-container">
  理解依赖注入与服务容器的工作原理。
</Card>

<Card title="服务提供者" icon="plug" href="/zh/service-providers">
  学习如何使用服务提供者引导应用。
</Card>


## Related topics

- [会话生命周期事件](/zh/packages/laravel-copilot-sdk/session-lifecycle-event.md)
- [⚡ Livewire 4 入门 —— 无需 JavaScript 也能做出响应式 UI](/zh/blog/livewire-introduction.md)
- [引擎 API 集成应用开发指南 - VOICEVOX for Laravel](/zh/packages/laravel-voicevox/app-guide.md)
- [Eloquent 入门](/zh/eloquent.md)
- [Laravel MCP](/zh/mcp.md)
