结束语
约 1476 字大约 5 分钟
2025-07-08
到这里,我们分析完了在php-fpm进程接收到nginx发起一个内部http请求后,Laravel框架是如何完整处理这个请求的。
在nginx阶段,nginx会把所有某个域名下的的http请求都转发给配置文件中定义目录(框架public目录)下的index.php文件,同时指定端口号。这里之所以要指定端口号,是因为在操作系统中,进程是以端口号来区分不同的服务。我们常见的9000端口,实际就是对应的php-fpm进程。
通过完整地分析一个php请求的生命周期,我们能清晰得看到Laravel框架的大致思路和结构。
现在回过头来看,大家有没有觉得,Laravel框架就像是构造了一套完整的结构精巧的组件。通过组合这些不同的组件,我们得到了一个能有效处理http请求的工具。
这个过程很像是搭乐高积木,乐高提前生产了一套可自由拼装的积木(组件),用户使用这些积木(组件)进行自由拼装,就能得到一个自己要想要的玩具。
或者我们更进一步得说,Container就像是Laravel提供的一个结构精巧的组件,用于处理类的依赖注入、类的自动构建以及类的缓存等等功能。而Application使用了这个组件的同时(Application继承了Container),又定义了很多其他不同的方法,使用这些方法来搭建一个完整的处理http请求的框架。它确实是起到了"胶水"(glue)的作用。
在Application类中,包含下面这些起粘贴组件作用的属性和方法:
属性:
当前框架版本号
框架所属基础路径
是否已经执行过bootstrap方法
是否已经执行过boot方法
启动中回调事件
启动后回调
结束回调
服务提供者数组
已加载服务提供者
延迟加载服务提供者
app路径
database路径
自定义存储文件路径
配置文件路径
配置文件名
app命名空间
方法:
- 获取当前框架版本号
- 注册基础绑定
- 注册基础服务提供者
- 引导执行bootstrapper数组中事件
- 注册加载配置文件后事件
- 注册"引导执行bootstrapper事件前"事件
- 注册"引导执行bootstrapper事件后"事件
- 判断是否执行过bootstrap事件
- 设置基础路径
- 绑定路径到容器
- 获取应用app目录路径
- 设置appPath
- 获取Laravel应用安装路径
- 获取bootstrap目录路径
- 获取config目录路径
- 获取database目录路径
- 设置database目录路径
- 获取lang目录路径
- 获取public目录路径
- 获取storage目录路径
- 设置storage目录路径
- 获取resouces目录路径
- 获取配置文件路径
- 设置配置文件路径
- 设置配置文件并返回对象application实例
- 获取配置文件名
- 获取配置文件完整路径(包含文件名)
- 获取或者判断当前应用环境
- 判断当前是否为local环境
- 判断当前是否为production环境
- 检测当前环境
- 判断当前是否处于命令行
- 判断当前是否处于单元测试
- 注册已配置服务提供者
- 注册服务提供者
- 获取对应的服务提供者(存在于已注册服务者成员数组中)
- 获取所有已注册服务提供者
- 解析一个服务提供者
- 标记服务提供者类为已注册
- 加载所有延迟服务提供者
- 加载指定延迟服务提供者
- 注册延迟服务提供者
- 解析一个字符串对应的类
- 判断给定的字符串是否已绑定
- 判断应用是否已启动
- 启动应用
- 启动服务提供者
- 注册启动中监听事件
- 注册启动后监听事件
- 触发应用回调事件
- 判断是否应跳过中间件
- 获取services.php缓存文件完整路径
- 获取packages.php缓存文件完整路径
- 判断应用配置文件是否已缓存
- 获取缓存配置文件完整路径
- 判断应用路由是否已缓存
- 获取缓存路由配置文件完整路径
- 判断应用事件是否已缓存
- 获取应用缓存事件文件完整路径
- 判断当前应用是否处于维护中
- 抛出一个http异常
- 注册应用结束回调事件
- 触发结束回调事件执行
- 获取已加载服务提供者
- 获取延迟加载服务提供者
- 设置延迟加载服务提供者
- 添加延迟加载服务提供者
- 判断是否是延迟服务提供者
- 配置实时facade命名空间
- 获取当前应用的locale配置值
- 设置当前应用的locale配置值
- 判断当前应用配置的locale值是否是给定值
- 注册核心别名类
- 清空应用中所有的绑定和事件
- 获取应用命名空间
列出上面这个列表,是为了让大家能更直观地感受到,为什么说Application类是Laravel框架中起调度作用的一个核心"胶水"类。
到这里,这段探寻Laravel生命周期的旅途已到终点。在分析源码的过程中,我们能看到Laravel的底层是使用面向对象的方式经过了复杂封装的,因此很多源码的实现细节我们并不能完全覆盖到,笔者相信阅读过这个系列的文章后你也可以用类似的方式自己去弄懂它们。
接下来,enjoy coding!
全文完