请求生命周期
简介
在现实世界中使用任何工具时,如果你理解该工具的工作原理,你会感到更有信心。应用程序开发也不例外。当你理解开发工具的功能时,你会感觉更舒适、更自信地使用它们。
本文档的目标是让你对 Laravel 框架的工作原理有一个良好的、高层次的了解。通过更好地了解整个框架,一切都会显得不那么"神奇",你在构建应用程序时会更有信心。如果你一开始不能理解所有术语,不要灰心!只需试着对正在发生的事情有一个基本的认识,随着你探索文档的其他部分,你的知识会不断增长。
生命周期概述
首要步骤
Laravel 应用程序的所有请求的入口点是 public/index.php
文件。所有请求都通过你的 Web 服务器(Apache / Nginx)配置被导向这个文件。index.php
文件并不包含太多代码。相反,它是加载框架其余部分的起点。
index.php
文件加载 Composer 生成的自动加载器定义,然后从 bootstrap/app.php
获取 Laravel 应用程序的实例。Laravel 本身采取的第一个动作是创建应用程序/服务容器的实例。
HTTP / Console 内核
接下来,根据进入应用程序的请求类型,传入的请求会被发送到 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
方法将响应内容发送到用户的网络浏览器。我们现在已经完成了整个 Laravel 请求生命周期的旅程!
深入服务提供者
服务提供者确实是引导 Laravel 应用程序的关键。创建应用程序实例,注册服务提供者,并将请求交给引导后的应用程序。就是这么简单!
通过服务提供者深入理解 Laravel 应用程序如何构建和引导是非常有价值的。你的应用程序的用户定义服务提供者存储在 app/Providers
目录中。
默认情况下,AppServiceProvider
基本上是空的。这个提供者是添加你的应用程序自己的引导和服务容器绑定的好地方。对于大型应用程序,你可能希望创建几个服务提供者,每个服务提供者都有更细粒度的引导,用于应用程序使用的特定服务。