自动加载的实现由`think\Loader`类
## 自动加载
由于新版`ThinkPHP`完全采用了命名空间的特性,因此只需要给类库正确定义所在的命名空间,而命名空间的路径与类库文件的目录一致,那么就可以实现类的自动加载。
类库的自动加载检测顺序如下:
1、类库映射检测;
2、`PSR-4`自动加载检测;
3、`PSR-0`自动加载检测;
系统会按顺序检测,一旦检测生效的话,就会自动载入对应的类库文件。
## 类库映射
遵循我们上面的命名空间定义规范的话,基本上可以完成类库的自动加载了,但是如果定义了较多的命名空间的话,效率会有所下降,所以,我们可以给常用的类库定义类库映射。命名类库映射相当于给类文件定义了一个别名,效率会比命名空间定位更高效,例如:
~~~
Loader::addClassMap('think\Log',LIB_PATH.'think\Log.php');
Loader::addClassMap('org\util\Array',LIB_PATH.'org\util\Array.php');
~~~
也可以利用`addClassMap`方法批量导入类库映射定义,例如:
~~~
$map = [
'think\Log' => LIB_PATH.'think\Log.php',
'org\util\array'=> LIB_PATH.'org\util\Array.php'
];
Loader::addClassMap($map);
~~~
>[danger] 注意词代码放到common.php或者start.php文件中
# import()方法
>[info]语法:
boolen import(class, baseUrl, ext)
实际执行的是:`Loader::import($class, $baseUrl, $ext)`
不推荐,此方法在5.1+被移除
| 参数 | 说明 |
| --- | --- |
| class | 必须,表示要导入的类库,具有命名空间的完整类。规则:目录分割符`DS`(/或\\)用`.`表示`.`用`#`表示 |
| baseUrl | 可选,表示导入的基础路径,最好以目录分割符结尾 |
| ext | 可选,表示导入的类库后缀,默认是 .php 。 |
当设置第二个参数且不是数组时,文件路径为`$baseUrl . $class . $ext;`
```
import('wechat-sdk.wechat', EXTEND_PATH, '.class.php');//引入 extend/wechat-sdk/wechat.class.php
```
当没有设置第二个参数时,他会优先先查找符合PSR-4的这个类,不存在则查找当前模块下的这个类,还不存在则查找extend目录下的这个类,还不存在则查找其他模块下的此类,最后都没找到则返回false
```
//相对路径以网站根目录作为起始目录(这里偷懒不想新建其他目录,单纯加载extend里的文件的话,第二个参数是可以省略的)
import('Test', '../extend');
//加载extend/user/Think.Test.php
import('user.Think#Test', '../extend');
//在application\admin\controller\Index.php里定义加载当前模块下的文件如(aplication/admin/Test/Alipay.class.php)
import('admin.Test.Alipay');
//或者
import('@.Test.Alipay');
```
### **vendor**()导入第三方类库
第一个参数中的.会解析成/ #会解析成.
加载vender文件夹下的文件还有一个方法省掉了路径
vendor($class, $ext = EXT)
实际调用`Loader::import($class, VENDOR_PATH, $ext);`
此函数在5.1被废除
```
vendor('alipaycustom.AopEncrypt');//vendor/alipaycustom/AopEncrypt.php
vendor('alipaycustom.alipaycustom#function');//vendor/alipaycustom/alipaycustom.function.php
```
## Composer自动加载
5.0版本支持`Composer`安装的类库的自动加载,你可以直接按照`Composer`依赖库中的命名空间直接调用。
# **框架自动加载实现流程**
## 1\. 首先载入loader.php文件 然后使用loader::register()进行自动加载 方法名中包含以下
![](https://img.kancloud.cn/06/9c/069c81b9d7f1a0660bdfbb915908ebbb_607x240.png)
## 2\. register()方法中
## 第一步使用sql\_autoload\_register()自动加载类
然后获取到composer路径并导入componser文件下的的auto\_static.php文件
auto\_static.php文件中 定义了两个静态属性:prefixLengthPsr4和prefixDirsPsr4
### prefixLengthPsr4 = array('t' => array('think\\componser' => 15),'a' => array('app'=>4))
### prefixDirsPsr4 = array('think\\componser' =>array(0 => '/top/think/think-installer/src'),'app' =>array(0=>'/application'))
![](https://img.kancloud.cn/41/66/416695b83f385960caee526dd4bf72b1_708x537.png)
接下来 获取到所有的类名数组 然后从使用array\_pop()数组中弹出最后一个数组
![](https://img.kancloud.cn/8d/de/8ddeecff1d4d5311974815a2e694a862_664x102.png)
Composer\Autoload\ComposerStaticInit25f893be97b63d60134b87b9c2e8987a
使用property_exists() 检查遍历的字符串是否在 上面的弹出的类数组中
![](https://img.kancloud.cn/f1/68/f16803f91dc30aea18618015cab2fc4a_923x201.png)
![](https://img.kancloud.cn/52/e2/52e2ab34900edb6d8881f3f9fd11be75_647x117.png)
![](https://img.kancloud.cn/08/b9/08b926a1b0ab85a7a737f9559fec4b28_1586x384.png)
## 3. 注册命名空间:
### 调用addNamespace() 参数是一个数组
参数是:
array(2) {
["think"]
=>string(57) "C:\Users\Administrator\Desktop\tp5\thinkphp\library\think"
["traits"]
=>string(58) "C:\Users\Administrator\Desktop\tp5\thinkphp\library\traits"}
![](https://img.kancloud.cn/c3/bf/c3bfb5cb4ce5df86a80d4341042b4086_793x164.png)
在addNamespace中 又调用了addPsr4()参数是(上面的数组)并执行遍历由原来的二维数组 遍历成结果是一维数组
![](https://img.kancloud.cn/af/fb/affb2acb1db9294781d04a8ed8011d04_971x342.png)
addPsr4的方法作用是添加Psr4空间
因为传过来的参数不为空 所以走流程如下图所示:
![](https://img.kancloud.cn/b7/4a/b74a218645c740cc1ba5bf3962979c53_983x723.png)
因为没有找到这个值 所以走这个逻辑:
![](https://img.kancloud.cn/8e/58/8e58103b1a2f9d7d4441f82378f6f0da_815x299.png)
最后就添加到了Psr4空间中
![](https://img.kancloud.cn/86/4f/864f7e41ba2754b5d75499aee5e17e8e_770x95.png)
![](https://img.kancloud.cn/d9/4b/d94bda38eabe5b4502f5bb442ba44553_763x476.png)
## 4. 加载类库映射文件
### 调用addClassMap()
因为已经使用命令创建了类库映射文件 所以走箭头逻辑
![](https://img.kancloud.cn/23/2f/232f1ea56c83e842e7ecd73562dba52d_492x61.png)
![](https://img.kancloud.cn/9d/eb/9debad8dfb3b6d0c6a82127d4cfadc9e_963x272.png)
addClassMap()参数是刚生成的classMap.php文件内容
把类库文件内容 赋值给**self::$classMap**
### 5. 自动加载extend目录
![](https://img.kancloud.cn/5f/80/5f8007a5381b56b730fef87c87c04ff1_638x105.png)
调用addAutoLoadDir()参数是extend的路径
在addAutoLoadDir中 把路径赋值给 **self::$fallbackDirsPsr4**
![](https://img.kancloud.cn/b3/41/b3415ad34df48e60eb2a8cffd55adf94_543x151.png)
# -----------分割线-----------
## 注册错误和异常处理机制
![](https://img.kancloud.cn/93/08/93083537e5a03fd028582ff3f80d1e0a_643x235.png)
### 1。Error类没有引用直接使用了 因此就出发了自动加载机制
就会自动调用Loader.php文件中的spl_autoload_register()
![](https://img.kancloud.cn/25/c1/25c1de8a3adc366fcabe298d2101968b_801x108.png)
就会调用autoload方法
![](https://img.kancloud.cn/ad/72/ad7256f08f90f50d47d3a31c41f2e3e4_811x515.png)
在autoload中 先查看是否有别名 没别名就调用findFile()去类库文件查找 因为Error在类库文件中找到了 如果找不到就去Psr-4中寻找 然后去查找 PSR-4 fallback dirs 然后查找 PSR-0 然后查找 PSR-0 fallback dirs一路查找 如果还没找到
return **self::$classMap[$class]** = false;
![](https://img.kancloud.cn/bc/4a/bc4a0e9adf13d7353c45c13fea0f88be_779x520.png)
- 目录结构与基础
- 修改数据后页面无变化
- 防跨目录设置
- input
- 系统目录
- 自动生成的文件以及目录
- 类自动加载
- url生成
- 数据增删改查
- 增加数据
- 数据更新
- 数据删除
- 数据查询
- 架构
- 生命周期
- 入口文件
- URL访问规则
- 配置
- 默认惯例配置配置
- 初始应用配置
- 路由
- 域名路由
- URL生成
- 数据库操作
- 方法列表
- 连接数据库
- 分布式数据库
- 查询构造器
- 查询数据
- 添加数据
- 更新数据
- 删除数据
- 查询语法
- 聚合查询(统计)
- 时间查询
- 高级查询
- 视图查询
- 子查询
- 辅助查询之链式操作
- where
- table
- alias
- field
- order
- limit
- page
- group
- having
- join
- union
- distinct
- lock
- cache
- comment
- fetchSql
- force
- bind
- partition
- strict
- failException
- sequence(pgsql专用)
- 查询事件
- 事务操作
- 监听SQL
- 存储过程
- 数据集
- 控制器
- 跳转和重定向
- 空控制器和空操作
- 分层控制器
- Rest控制器
- 资源控制器
- 自动定位控制器
- tp3的增删改查
- 方法注入
- 模型
- 属性方法一览
- 类方法详解
- Model
- 调用model不存在的属性
- 调用model中不存在的方法
- 调用model中不存在的静态方法
- hasOne
- belongsTo
- hasMany {Relation}
- belongsToMany
- hasManyThrough
- morphMany
- morphOne
- morphTo
- ::hasWhere {Query}
- ::has
- relationCount
- data 【model】
- setInc {integer|true}
- setDec {integer|true}
- save {integer | false}
- saveAll {array}
- delete {integer}
- ::get 查询单条数据 {Model}
- ::all 查询多条数据{Model [ ]}
- ::create 新增单条数据 {Model}
- ::update 更新单条数据 {Model}
- ::destroy {integer}
- ::scope {Query}
- getAttr {mixed}
- xxx
- append
- appendRelationAttr
- hidden
- visible
- except
- readonly
- auto
- together
- allowField
- isUpdate
- validate
- toCollection
- toJson
- toArray
- 定义
- 新增
- 更新
- 查询
- 删除
- 聚合
- 获取器
- 修改器
- 时间戳
- 只读字段
- 软删除
- 类型转换
- 数据完成
- 查询范围
- 模型分层
- 数组访问和转换
- JSON序列化
- 事件
- 关联
- 一对一关联
- 主表一对一关联
- 从表一对一关联(相对关联)
- 一对多关联
- 主表定义一对多关联
- 从表定义一对多关联
- 远程一对多
- 多对多关联
- 多态关联
- 动态属性
- 关联预载入with()
- 关联统计
- N+1查询
- 聚合模型
- Model方法集合
- 表单验证
- 验证器
- 验证规则
- 错误信息
- 验证场景
- 控制器验证
- 模型验证
- 内置规则
- 静态调用
- 表单令牌
- Token身份令牌
- 视图
- 模版
- 变量输出
- 函数输出
- Request请求参数
- 模板注释及原样输出
- 三元运算
- 内置标签
- 模板继承
- 模板布局
- 日志
- 日志初始化
- 日志驱动
- 日志写入
- 独立日志
- 日志清空
- 写入授权
- 自定义日志
- 错误和调试
- 异常
- php系统异常及thinkphp5异常机制
- 异常处理
- 抛出异常
- 异常封装
- resful
- 404页面
- 调试模式
- Trace调试
- SQL调试
- 变量调试
- 性能调试
- 远程调试
- 安全
- 输入安全
- 数据库安全
- 上传安全
- 其它安全建议
- xss过滤
- 扩展
- 函数
- 类库
- 行为
- 驱动
- Composer包
- Time
- 数据库迁移工具
- Workerman
- MongoDb
- htmlpurifier XSS过滤
- 新浪SAE
- oauth2.0
- 命令行及生成文件
- 系统现成命令
- 创建类库文件
- 生成类库映射文件
- 生成路由缓存
- 清除缓存文件
- 生成配置缓存文件
- 生成数据表字段缓存
- 自定义命令行
- 开始
- 调用命令
- 杂项
- 助手函数
- URL重写
- 缓存
- 缓存总结
- Session
- Cookie
- 多语言
- 分页
- 上传
- 验证码
- 图像处理
- 文件处理
- 单元测试
- 自定义表单令牌