技术博客
深入理解ThinkPHP的Loader自动加载
admin2021-01-20 09:44
1015人已围观
简介想了很久终于要开始系列文章的编写了,期望是写出提升和面试都可以搞定的系列文章。 当你看到本文时,如果你发现咔咔没有编写到的面试热点问题或者技术难点,期待评论区指
前言
目前在整理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.获取最后一个类ComposerStaticInit30742487e00917c888d89ba216f165b9
6.判断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
的加载方式
四、总结
关于类自动加载的所有流程就完成了,如有错误之处可以在评论区哦!
❝坚持学习、坚持写博、坚持分享是咔咔从业以来一直所秉持的信念。希望在偌大互联网中咔咔的文章能带给你一丝丝帮助。我是咔咔,下期见。
❞

微信公众号
很赞哦!(0)
相关文章
文章评论
评论0
站点信息
- 微信公众号:扫描二维码,关注我们

点击排行

标签云
-
php
网页设计
个人博客
JS
个人博客
Html
春节必看: 2020新春红包大战 全攻略
新增详细玩法攻略!
支付宝集五福5亿集分宝招商银行抽现金券抖
抖音 2020 发财中国年 攻略
支付宝集五福5亿集分宝招商银行抽现金券抖
最近购买威尔胜WTB0900复刻版和WT
mysql慢查询和php-fpm慢日志
PSR-2
基础代码规范
Thinkphp
响应式
公司
整站
源码
网络科技网站模板
1024
节日
百度收录
论坛
社区
2020
豆瓣
评分最高
电影
debugger
调试
Python
语法
高德
百度地图
MySQL
追寻
webpack
vue
oracle
服务器搭建
有趣
动物
人体
历史
天文
生活
名人
体育
地理
文化
科学
心理
植物
饮食
自然
图片
JVM
IDEA
Loader
Git
UNIAPP
股票
A股
同花顺
海尔
海天味业
半年报
股市总结
歌尔股份
乐普医疗
涪陵榨菜
餐饮
财报分析
酒店
年报分析
美锦能源
山煤国际
贵州茅台
张坤
腾讯
华鲁恒升
淮北矿业
药明康德
早盘关注
国电电力
北方华创
宝丰能源
TCL中环
兔宝宝
天润乳业
启明星辰
阳光电源
山西汾酒
迈瑞医疗
人福医药
比亚迪
宁德时代
汤臣倍健
伊利股份
通威股份
东鹏饮料
隆基股份
紫金矿业
五粮液
康龙化成
赣锋锂业
爱尔眼科
片仔癀
VR
永新股份
爱美客
美的集团
格力电器
科沃斯
云南白药
同仁堂
洋河股份
白云山
三体
狂飙 原著