请求生命周期
简介
在“现实世界”中使用任何工具时,如果你了解该工具的工作原理,你会更有信心。应用程序开发也是如此。当你了解你的开发工具是如何工作的时,你会感觉更舒适和更有信心使用它们。
本文档的目的是为你提供一个关于 Laravel 框架如何工作的良好概述。通过更好地了解框架的整体,一切都会变得不那么“神奇”,你将更有信心构建你的应用程序。如果你不立即理解所有术语,不要灰心!只要尝试了解正在发生的事情,你的知识会在你探索文档的其他部分时不断增长。
生命周期概述
第一步
所有对 Laravel 应用程序的请求的入口点是 public/index.php
文件。所有请求都由你的 Web 服务器(Apache / Nginx)配置定向到此文件。index.php
文件中没有多少代码。相反,它是加载其余框架的起点。
index.php
文件加载 Composer 生成的自动加载定义,然后从 bootstrap/app.php
中获取 Laravel 应用程序的实例。Laravel 本身采取的第一个操作是创建一个应用程序 / 服务容器 的实例。
HTTP / 控制台内核
接下来,传入请求将发送到 HTTP 内核或控制台内核,使用应用程序实例的 handleRequest
或 handleCommand
方法,具体取决于进入应用程序的请求类型。这两个内核充当所有请求流经的中心位置。现在,让我们只关注 HTTP 内核,它是 Illuminate\Foundation\Http\Kernel
的一个实例。
HTTP 内核定义了一个将在请求执行之前运行的 bootstrappers
数组。这些引导程序配置错误处理、配置日志记录、检测应用程序环境,以及在实际处理请求之前需要执行的其他任务。通常,这些类处理你不需要担心的内部 Laravel 配置。
HTTP 内核还负责将请求传递给应用程序的中间件堆栈。这些中间件处理读取和写入 HTTP 会话、确定应用程序是否处于维护模式、验证 CSRF 令牌 等等。我们很快将对此进行更多讨论。
HTTP 内核的 handle
方法的签名非常简单:它接收一个 Request
并返回一个 Response
。将内核视为一个大型黑盒,它代表你的整个应用程序。向它提供 HTTP 请求,它将返回 HTTP 响应。
服务提供者
最关键的内核引导操作之一是加载应用程序的 服务提供者。服务提供者负责引导框架的所有各种组件,例如数据库、队列、验证和路由组件。
Laravel 将遍历此提供者列表并实例化每个提供者。在实例化提供者之后,将调用所有提供者的 register
方法。然后,一旦所有提供者都已注册,将调用每个提供者的 boot
方法。这是为了使服务提供者能够在他们的 boot
方法执行之前依赖于所有容器绑定被注册和可用。
基本上 Laravel 提供的每个主要功能都是由服务提供者引导和配置的。由于它们引导和配置了框架提供的许多功能,服务提供者是整个 Laravel 引导过程最重要的方面。
虽然框架内部使用数十个服务提供者,但你也可以创建自己的服务提供者。你可以在 bootstrap/providers.php
文件中找到应用程序正在使用的用户定义或第三方服务提供者的列表。
路由
一旦应用程序已引导并且所有服务提供者都已注册,Request
将被传递给路由器以进行分发。路由器将请求分发到路由或控制器,并运行任何路由特定的中间件。
中间件提供了一种方便的机制来过滤或检查进入应用程序的 HTTP 请求。例如,Laravel 包含一个中间件,它验证应用程序的用户是否已身份验证。如果用户未经身份验证,中间件将重定向用户到登录屏幕。但是,如果用户已身份验证,中间件将允许请求继续进入应用程序。某些中间件分配给应用程序中的所有路由,例如 PreventRequestsDuringMaintenance
,而某些中间件仅分配给特定的路由或路由组。你可以阅读完整的 中间件文档,了解更多关于中间件的信息。
如果请求通过了所有匹配路由分配的中间件,则将执行路由或控制器方法,并且路由或控制器方法返回的响应将被发送回路由的中间件链。
收尾
一旦路由或控制器方法返回响应,响应将向外返回通过路由的中间件,从而使应用程序有机会修改或检查传出的响应。
最后,一旦响应通过中间件返回,HTTP 内核的 handle
方法将响应对象返回到应用程序实例的 handleRequest
,并且此方法调用返回的响应的 send
方法。send
方法将响应内容发送到用户的 Web 浏览器。我们现在已经完成了对整个 Laravel 请求生命周期的旅程!
关注服务提供者
服务提供者确实是引导 Laravel 应用程序的关键。应用程序实例被创建,服务提供者被注册,并且请求被传递给引导的应用程序。就是这么简单!
牢固地掌握 Laravel 应用程序是如何通过服务提供者构建和引导的非常有价值。你应用程序的用户定义服务提供者存储在 app/Providers
目录中。
默认情况下,AppServiceProvider
相当空。此提供者是添加你应用程序自己的引导和服务容器绑定的绝佳位置。对于大型应用程序,你可能希望创建多个服务提供者,每个服务提供者都针对应用程序使用的特定服务进行更细粒度的引导。