
# 请求生命周期

-   [介绍](#introduction)
-   [生命周期概览](#lifecycle-overview)
    -   [第一步](#first-steps)
    -   [HTTP / 控制台内核](#http-console-kernels)
    -   [服务提供者](#service-providers)
    -   [路由](#routing)
    -   [收尾工作](#finishing-up)
-   [聚焦服务提供者](#focus-on-service-providers)

## 介绍

在“真实世界”中使用任何工具时，如果你了解这个工具的工作原理，你会更有信心。应用程序开发也不例外。当你了解开发工具如何运行时，你在使用它们时会感到更舒适、更自信。

本文档的目标是为你提供一个良好的、高层次的 Laravel 框架工作原理概览。通过更好地了解整个框架，一切都会显得不那么“神奇”，你在构建应用程序时也会更有信心。如果你一开始没有理解所有术语，不要灰心！只需要先大致了解正在发生什么，随着你探索文档的其他章节，你的知识会逐渐增长。

## 生命周期概览

### 第一步

Laravel 应用程序所有请求的入口点都是 `public/index.php` 文件。所有请求都会通过你的 Web 服务器（Apache / Nginx）配置被定向到此文件。`index.php` 文件本身并不包含太多代码。相反，它是加载框架其余部分的起点。

`index.php` 文件会加载 Composer 生成的自动加载器定义，然后从 `bootstrap/app.php` 中获取 Laravel 应用程序的一个实例。Laravel 自身执行的第一个操作是创建应用程序 / [服务容器](/docs/laravel/13.x/container) 的一个实例。



### HTTP / 控制台内核

接下来，传入的请求会根据进入应用程序的请求类型，使用应用程序实例的 `handleRequest` 或 `handleCommand` 方法，被发送到 HTTP 内核或控制台内核。这两个内核作为所有请求流经的中心位置。现在，我们先只关注 HTTP 内核，它是 `Illuminate\Foundation\Http\Kernel` 的一个实例。

HTTP 内核定义了一个 `bootstrappers` 数组，这些引导程序会在请求被执行之前运行。这些引导程序会配置错误处理、配置日志记录、[检测应用程序环境](/docs/laravel/13.x/configuration#environment-configuration)，并执行其他在请求真正被处理之前需要完成的任务。通常，这些类处理的是 Laravel 内部配置，你不需要担心它们。

HTTP 内核还负责将请求传递通过应用程序的中间件栈。这些中间件会处理读取和写入 [HTTP 会话](/docs/laravel/13.x/session)、判断应用程序是否处于维护模式、[验证 CSRF 令牌](/docs/laravel/13.x/csrf) 等工作。我们很快会进一步讨论这些内容。

HTTP 内核的 `handle` 方法签名非常简单：它接收一个 `Request` 并返回一个 `Response`。可以把内核想象成一个代表整个应用程序的大黑盒。向它传入 HTTP 请求，它就会返回 HTTP 响应。

### 服务提供者

内核最重要的引导操作之一，就是加载应用程序的 [服务提供者](/docs/laravel/13.x/providers)。服务提供者负责引导框架的各种组件，例如数据库、队列、验证和路由组件。



Laravel 会遍历这个提供者列表，并实例化其中的每一个提供者。在实例化这些提供者之后，会调用所有提供者的 `register` 方法。然后，当所有提供者都完成注册后，会调用每个提供者的 `boot` 方法。这样做是为了确保服务提供者在其 `boot` 方法执行时，可以依赖每一个容器绑定都已经被注册并可用。

本质上，Laravel 提供的每一个主要功能，都是由服务提供者进行引导和配置的。由于服务提供者会引导并配置框架提供的如此多功能，因此服务提供者是整个 Laravel 引导过程中最重要的部分。

虽然框架内部使用了数十个服务提供者，但你也可以选择创建自己的服务提供者。你可以在 `bootstrap/providers.php` 文件中找到应用程序正在使用的用户自定义或第三方服务提供者列表。

### 路由

一旦应用程序完成引导，并且所有服务提供者都已经注册，`Request` 就会被交给路由器进行分发。路由器会将请求分发到某个路由或控制器，同时运行任何特定于路由的中间件。

中间件为过滤或检查进入应用程序的 HTTP 请求提供了一种便捷机制。例如，Laravel 包含一个中间件，用于验证应用程序的用户是否已通过身份认证。如果用户未通过身份认证，中间件会将用户重定向到登录页面。但是，如果用户已通过身份认证，中间件会允许请求继续深入应用程序。有些中间件会分配给应用程序内的所有路由，例如 `PreventRequestsDuringMaintenance`，而有些中间件只会分配给特定路由或路由组。你可以通过阅读完整的 [中间件文档](/docs/laravel/13.x/middleware) 来了解更多关于中间件的内容。



如果请求通过了匹配路由所分配的所有中间件，那么路由或控制器方法就会被执行，并且路由或控制器方法返回的响应会通过该路由的中间件链返回。

### 收尾工作

一旦路由或控制器方法返回响应，该响应就会通过路由的中间件向外返回，从而让应用程序有机会修改或检查传出的响应。

最后，一旦响应通过中间件返回，HTTP 内核的 `handle` 方法会将响应对象返回给应用程序实例的 `handleRequest` 方法，而该方法会调用返回响应上的 `send` 方法。`send` 方法会将响应内容发送到用户的 Web 浏览器。至此，我们已经完成了整个 Laravel 请求生命周期的旅程！

## 聚焦服务提供者

服务提供者确实是引导 Laravel 应用程序的关键。应用程序实例被创建，服务提供者被注册，然后请求被交给已经完成引导的应用程序。事情真的就是这么简单！

牢固掌握 Laravel 应用程序如何通过服务提供者构建和引导，是非常有价值的。你的应用程序中用户定义的服务提供者存放在 `app/Providers` 目录中。

默认情况下，`AppServiceProvider` 相当空。这个提供者是添加你的应用程序自身引导逻辑和服务容器绑定的绝佳位置。对于大型应用程序，你可能希望创建多个服务提供者，每个服务提供者都针对应用程序使用的特定服务进行更细粒度的引导。

