请求生命周期
简介
在「现实世界」中使用任何工具时,了解其工作原理会让你更有信心。应用开发也是如此。当你理解开发工具如何运作时,使用起来会更加从容自信。
本文旨在从较高层面概述 Laravel 框架的工作方式。更好地了解框架整体后,一切都会显得不那么「神奇」,你也会更有信心构建应用。如果一时无法理解所有术语,也不要气馁!先建立基本认识即可,随着阅读文档其他部分,你的知识会不断增长。
生命周期概览
第一步
所有发往 Laravel 应用的请求,入口都是 public/index.php 文件。Web 服务器(Apache / Nginx)的配置会把全部请求导向该文件。index.php 本身代码不多,它主要是加载框架其余部分的起点。
index.php 会加载 Composer 生成的自动加载定义,然后从 bootstrap/app.php 获取 Laravel 应用实例。Laravel 自身执行的第一步,是创建应用 / 服务容器 实例。
HTTP / 控制台内核
接下来,根据进入应用的请求类型,传入请求会通过应用实例的 handleRequest 或 handleCommand 方法,分别交给 HTTP 内核或控制台内核处理。这两个内核是所有请求流经的中枢。眼下我们先关注 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 几乎是空的。它很适合用来添加应用自身的引导逻辑和服务容器绑定。对于大型应用,你可能希望创建多个服务提供者,分别对应用使用的特定服务做更细粒度的引导。