前文
Composer 下载ThinkPHP5.1
的源码,每个框架它都必须都有一个“类的自动加载”机制 ,我们都知道PHP引入文件是需要require
、 include
才能使用别的类文件中的方法。
比如我需要写一个公共文件 model.php
include "model.php"
include "model2.php"
class User {
//code..
}
但是!如何当公共类库文件很多的时候,每次都需要手动引入,就显得非常麻烦,不利于/不方便维护管理。
所以PHP引入了一个spl_autoload_register()
的类自动加载,TP框架就是借助了 spl_autoload_register()
来完成类的自动加载。
TP5框架入口加载机制
学习框架源码的第一步,先找到入口文件 public/index.php
,然后一步步跟进流程,看下代码执行的过程。
- 第一行:定义命名空间就不赘述了。。
- 第二行:去加载基础文件
base.php
,是位于上一层目录的 think目录下
打开Base.php ,第16行就会去加载 Loader.php
文件 (就是TP5自动加载的类库) ,Loader.php 是TP5封装的底层基础类库。
再引用了核心文件 Loader.php
调用类库的 Loader::register()
的方法
发现都用了
spl_autoload_register()
的系统函数,其他框架也是同理。
都是会在框架的第一步“入门文件”就进行类的自动加载机制,针对底层进行封装。
TP5中的Loader::register() 其实做了2件事:
- 内部自定义一个
autoload()
去进行框架的底层深度封装 - 为了支持 Composer 自动加载 安装第三方的类库插件(Vendor),都是遵循PSR-4的风格统一,那么加载composer类的
autoload_static.php
后,再去加载对应的插件类库。
分析Loader::register的执行流程
如下截图:
-
分析TP5执行
Loader::register()
的注册自动加载方法 ,( 是调用不存在的类的时候才会执行spl_autoload_register()
) -
运用3元运算符,如果有参数就执行其他自定义类,没就 加载本类的
autoload()
方法 -
调用
self::gerRootPath()
获取项目的根目录 -
这里就是走 Composer的加载机制,然后组织一个Vendor的决定路径 ,
self::$composerPath
-
判断是否有Vendor的目录,再判断是否有
auto_static
的文件 ,有就加载composer目录下的auto_static.php
分析Composer自动加载——类文件
在逻辑往下走,判断是否有Vendor的目录,再判断是否有auto_static
的文件 ,有就加载composer目录下的auto_static.php
auto_static.php
发现定义了2个属性分别是: $prefixLengthsPsr4
、$prefixDirsPsr4
,这是什么意思呢?
定义数组,有个key和value,比如 $prefixLengthsPsr4 (PSR4的长度)
t
key代表一个命名空间 ,代表think\composer\
命名空间 ,首字母代表类,把某些类放进去来,15
代表字符的长度。a
key也是代表一个命名空间,代表:app
,用首字母代表,把某些类放进去,4
是这个字符的长度。
2个斜线是转义字符,比如
think\\composer\\
等同于think\composer\
$prefixDirsPsr4 把每个命名空间的类对应的目录列出来
- 比如
think\composer
这个命名空间 在src下 app\\
这个命名空间就在根目录的application
比如通过 Compsoe r安装 swoole、workermam、phpexcel 就把相应的规则追加数组上 填进来。
总结: composer的统一加载机制的地方,每次composer新类库的时候,都会往这个属性追加
命名空间
以及类库的目录路径
。
分析Composer自动加载——属性赋值
回到Loader::register()方法。
// Composer自动加载支持
if (is_dir(self::$composerPath)) {
if (is_file(self::