ThinkPHP自动加载Loader源码解析
发布时间 - 2020-09-16 00:00:00 点击率:次❝想了很久终于要开始系列文章的编写了,期望是写出提升和面试都可以搞定的系列文章。 当你看到本文时,如果你发现咔咔没有编写到的面试热点问题或者技术难点,期待评论区指出,一起完善。
❞
前言
目前在整理PHP进阶路线图,如有好的建议咔咔会第一时间进行收录。
一、自动加载loader源码分析
1-1 学习目标
类的自动加载 类自动加载的俩种方式 spl_autoload_register必须会使用 实现自定义文件的类的自动加载
1-2 Composer加载
从上图咔咔给的解析图,在base.php中首先加载了loader类,接着调用了register这个方法。
来到thinkphp\library\think\Loader.php有一个register的方法,在这个方法里边,我们先学习第一个知识点spl_autoload_register()聊聊spl_autoload_register前世今生和简单使用,直接点击即可查看。
紧接着就是项目的根路径和composer的路径。
从这里开始就是在加载composer文件,过程也是很简单
1.判断composer是否为目录 2.判断路径下面的autoload_static.php是否为文件 3.引入autoload_static.php文件 4.返回所有已经声明的所有类 数组返回 5.获取最后一个类ComposerSta
ticInit30742487e00917c888d89ba216f165b96.判断ComposerStaticInit30742487e00917c888d89ba216f165b9中是否存在数组中的数据
接着可以去vendor\composer\autoload_static.php文件中可以看到这俩个属性
这里有一段代码估计有一部分同学会在这里绕一下self::${$attr} = $composerClass::${$attr};,这里的$attr就是'prefixLengthsPsr4', 'prefixDirsPsr4', 'fallbackDirsPsr4', 'prefixesPsr0', 'fallbackDirsPsr0', 'classMap', 'files'这些数据,外层在加一个$符号。
从而在ComposerStaticInit30742487e00917c888d89ba216f165b9这个类中直接获取对应的属性值,也就是上图的俩个属性值。
1-3 注册命名空间
文件还是thinkphp\library\think\Loader.php的register方法
在这里注册了俩个命令空间,分别为think和traits。然后会进入到addNamespace这个方法中在addNamespace方法中,添加了Psr4空间
接着来到addPsr4这个方法,会把这俩个命名空间都注册到ComposerStaticInit1e269472f484e157e90227b420ffca7a类的$prefixLengthsPsr4和$prefixDirsPsr4这俩个属性中
为了验证上面做一个断点调试,看到这些数据就应该清晰了,至于traits也是一样的注册方式。
截止到这里命名空间就注册完成了,接下来研究一下psr4命名空间是个什么东东。
1-4 Psr4是什么玩意
psr是简单的理解就是文件路径、自动加载对应类的相关规范、目前TP5.1使用的是psr4规范
此处的类是指class、接口、超类结构
一个完整的类需要一下结构\(\)*\
以下规范来源于PHP文档
完整的类名必须要有一个顶级命名空间,被称为 "vendor namespace";
完整的类名可以有一个或多个子命名空间;
完整的类名必须有一个最终的类名;
完整的类名中任意一部分中的下滑线都是没有特殊含义的;
完整的类名可以由任意大小写字母组成;
所有类名都必须是大小写敏感的。
以下是官方给的一个例子,这个psr规范能理解就尽量去理解它
1-5 加载类库映射文件
到这里,肯定会有一个疑问,这里怎么没有classmap.php这个文件。不急不慌,先执行php think optimize:autoload把文件弄出来最终会走到addClassMap这个方法,在这个方法中,只是把classmap.php这个文件的数据赋值给$classMap 而已,没有什么其它的用法
1-6 自动加载extend目录
extend这个目录用过TP框架的都多少用过的,在这个目录里边可以存放一下自定义的类库文件。
根据下图可以看到就是使用addAutoLoadDir这个方法进行加载的
在方法中也仅仅是把extend的路径赋值给了$fallbackDirsPsr4这个属性。
截止到这里Loader::register();这部分就结束了,接着我们深入的看一下内部实现和实践案例。
在以上阅读源码中有四个属性,简单的整理一下
二、简说类的加载过程
在刚刚开始解析这里的源码时就有一个函数spl_autoload_register
当需要使用的类没有被引入时,这个函数会在PHP报错前被触发,未定义的类名会被当作参数传入这里会直接去执行think\\Loader::autoload这个方法
经过断点第一个未加载的类就是think\Error
为什么是think\Error呢!可以在回到thinkphp/base.php看一下,当自动加载完执行完成后第一个执行的类就是Error
可以简单的做个测试,将这Error改为Kaka,进行打印一下,这时的类就改变为Kaka。到这里大家对这个类的自动加载机制就有一定的了解了。
当使用的类没有被引入时会把这个类当做参数传到thinkphp/library/think/Loader.php的autoload方法中。
到这里在进行看一下autoload这个方法
先从findFile这个方法走,把未因为的类传入这个方法中,在findFile这个方法中会直接从classMap这个属性中直接把think\Error这个类映射的文件直接返回出来
将think\Error这个类的完整路径返回给autoload的file变量后,把win环境的大小写给判断了一次。
然后直接使用include引入文件即可,直到返回。
直到这里就是一次完整的类的自动加载解析。
虽然到这里结束了,但是还是得在提一点就是$classMap这个属性,这个属性是基于文件classmap.php来到,这个文件的生成也是需要执行命令php think optimize:autoload生成的。
当没有生成这个文件时程序是如何执行的呢!
之前的所有流程都是一样的,只有在findFile这里不一样,接下来进行简单的梳理一下。
这时代码肯定不会走classMap
先获取think\Error文件
然后经过Composer自动加载中的俩个属性进行获取命名空间,在把think\Error.php文件进行拼接
最终返回的结果也是D:\phpstudy_pro\WWW\ThinkPHPSourceCodeAnalysis\thinkphp\library\think\Error.php这个文件。
这里的代码需要好好的阅读一下。
类的自动加载到这里就是完全结束了。
三、自定义文件如何实现类的自动加载
先创建一个文件夹kaka
这时在控制器index中引入文件Kaka.php
直接进行访问,这时这个类肯定会报错,那么我们应该怎么操作一下,就可以直接访问呢!
这个时候就提现到源码的重要性了,还记得在自动加载的register函数中,加载过extend目录
这时在加一个kaka这个目录,直接进行访问一下
没毛病,直接就出来了。一切OK在这里在聊一下关于extent的加载方式
在之前聊注册自动加载类库目录只是说明了一下只是把路径存到了$fallbackDirsPsr4属性,没有细细说,接下来就是说明这些了。
阅读源码只能是实现那然后查看那
只要是定义的类都会进去到autoload进行自动加载
同样也会进入到findFile这个方法
在findFile这个方法中可以看到这段代码,这个属性是不是很熟悉,就是自动加载extend目录时添加到$fallbackDirsPsr4属性的。
当在findFile中打印参数class时看一下数据
很清楚地可以看到test\Kaka这个类
此时在打印一下这个$fallbackDirsPsr4属性里边返回的file
然后就是使用__include_file来直接includeD:\phpstudy_pro\WWW\ThinkPHPSourceCodeAnalysis\kaka\test\Kaka.php我们定义的文件。
以上的这个自定义文件如何实现类的自动加载,并且也就是extend的加载方式
四、总结
关于类自动加载的所有流程就完成了,如有错误之处可以在评论区哦!
❝坚持学习、坚持写博、坚持分享是咔咔从业以来一直所秉持的信念。希望在偌大互联网中咔咔的文章能带给你一丝丝帮助。我是咔咔,下期见。
❞
# thinkphp
# php
# composer
# 命名空间
# include
# Error
# register
# 接口
# class
# Namespace
# 编辑器
# 在这里
# 自动加载
# 加载
# 插入图片
# 咔咔
# 有一个
# 可以看到
# 自定义
# 看一下
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
悟空浏览器如何设置小说背景色_悟空浏览器背景色设置【方法】
html5怎么画眼睛_HT5用Canvas或SVG画眼球瞳孔加JS控制动态【绘制】
微信小程序 配置文件详细介绍
如何快速搭建安全的FTP站点?
php8.4header发送头信息失败怎么办_php8.4header函数问题解决【解答】
如何确保FTP站点访问权限与数据传输安全?
Bootstrap整体框架之CSS12栅格系统
高端网站建设与定制开发一站式解决方案 中企动力
Linux后台任务运行方法_nohup与&使用技巧【技巧】
在Oracle关闭情况下如何修改spfile的参数
如何在建站主机中优化服务器配置?
浅谈javascript alert和confirm的美化
Python并发异常传播_错误处理解析【教程】
如何在Ubuntu系统下快速搭建WordPress个人网站?
Laravel怎么实现观察者模式Observer_Laravel模型事件监听与解耦开发【指南】
VIVO手机上del键无效OnKeyListener不响应的原因及解决方法
公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?
JavaScript Ajax实现异步通信
如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】
如何自定义建站之星网站的导航菜单样式?
PythonWeb开发入门教程_Flask快速构建Web应用
专业商城网站制作公司有哪些,pi商城官网是哪个?
JS弹性运动实现方法分析
如何快速搭建虚拟主机网站?新手必看指南
如何批量查询域名的建站时间记录?
Swift开发中switch语句值绑定模式
Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】
如何在腾讯云服务器快速搭建个人网站?
阿里云高弹*务器配置方案|支持分布式架构与多节点部署
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
Laravel中的Facade(门面)到底是什么原理
如何在云主机快速搭建网站站点?
高性能网站服务器部署指南:稳定运行与安全配置优化方案
电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?
湖南网站制作公司,湖南上善若水科技有限公司做什么的?
详解Android——蓝牙技术 带你实现终端间数据传输
高防服务器如何保障网站安全无虞?
C#如何调用原生C++ COM对象详解
Laravel如何发送系统通知?(Notification渠道示例)
Laravel如何处理CORS跨域问题_Laravel项目CORS配置与解决方案
Bootstrap整体框架之JavaScript插件架构
如何获取上海专业网站定制建站电话?
深圳网站制作平台,深圳市做网站好的公司有哪些?
Swift中循环语句中的转移语句 break 和 continue
Laravel怎么实现模型属性的自动加密
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比
谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复
Laravel中间件如何使用_Laravel自定义中间件实现权限控制
如何在阿里云虚拟主机上快速搭建个人网站?


ticInit30742487e00917c888d89ba216f165b9