[TOC]
* * * * *
## 1 加载器接口
### 加载器初始化
>[info] 注册加载器函数
`public static function register($autoload = '')`
> $autoload: 加载器函数 默认为Loader::autoload()
* * * * *
### 注册命名空间/类名别名
>[info] 注册命名空间别名
`public static function addNamespace($namespace, $path = '')`
> $namespace:待注册命名空间
> $path:待注册命名空间对应目录
* * * * *
>[info] 注册类名别名
`public static function addMap($class, $map = '')`
> $class:待注册类名
> $map:待注册类名对应别名
* * * * *
### 加载文件
>[info] 类Java加载函数
`public static function import($class, $baseUrl = '', $ext = EXT) `
> $class:加载的类名
> $baseUrl:加载的类文件目录
> $ext:加载的文件后缀
* * * * *
>[info] 类自动加载
`public static function autoload($class) `
> $class:加载的类名
## 2 加载器原理
### 加载器初始化 Loader::rigister()
`spl_autoload_register($autoload ? $autoload : 'think\\Loader::autoload');`
注册系统自动加载$autolaod
`self::registerComposerLoader();`
注册composer自动加载
* * * * *
>[info] composer自动加载注册 Loader::registerComposerLoader()
composer自动加载原理见 [php的自动加载](http://www.kancloud.cn/zmwtp/tp5/119447#4-composer-)
`if (is_file(VENDOR_PATH . 'composer/autoload_namespaces.php')) {}`
composer/autoload_namespaces.php注册到self::$prefixesPsr0
`if (is_file(VENDOR_PATH . 'composer/autoload_psr4.php')) {}`
composer/autoload_psr4.php注册到self::$prefixDirsPsr4[$namespace]
`if (is_file(VENDOR_PATH . 'composer/autoload_classmap.php')) {}`
composer/autoload_classmap.php注册到self::$map
`if (is_file(VENDOR_PATH . 'composer/autoload_files.php')) {}`
composer/autoload_files.php中文件依次加载
### 命名空间与目录关系注册 Loader::addNamespace()
`self::$namespace = array_merge(self::$namespace, $namespace);`
$namespae为 array('namespace1'=>'path1','namespace2'=>'path2'),
$path为空时,将$namespace合并到self::$namespace。
`self::$namespace[$namespace] = $path;`
两个参数则注册$namespace与$path到self::$namespace
### 类名与文件关系注册 Loader::addMap()
`self::$map = array_merge(self::$map, $class);`
$class为array('class1'=>'map1','class2'=>'map2')
$map为空时,将$class合并到self::$map。
`self::$map[$class] = $map;`
两个参数注册$class与$map关联到self::$map
### 文件自动加载 Loader::autoload()
`if (isset(self::$map[$class])) {}`
首先检查类别名对应的类文件,
如果存在,则加载对应类文件
`elseif ($file = self::findFileInComposer($class)) {}`
次之使用Composer加载对应类文件
`else {}`
最后解析类名中的命名空间,类到对应文件,并加载
### 文件手动加载 Loader::import()
`static $_file = [];`
手动加载文件的全局缓存数组
$class参数解析:
`$class = str_replace(['.', '#'], [DS, '.'], $class);`
将$class参数中的符号"." "#"解析为目录分隔符,
~~~
if (isset($_file[$class . $baseUrl])) {
return true;
} else {
$_file[$class . $baseUrl] = true;
}
~~~
检查$_file全局缓存数组是否已加载。
$baseUrl参数解析:
`if (empty($baseUrl)) {}else{}`
检查是否添加$baseUrl参数。
`list($name, $class) = explode(DS, $class, 2);`
将$class以目录分割符分解为到目录名$name,文件名$class变量中
~~~
if (isset(self::$namespace[$name])) {
$baseUrl = self::$namespace[$name];
}
~~~
$name对应的目录已注册到$namespace,获取对应目录。
~~~
elseif ('@' == $name || MODULE_NAME == $name) {
$baseUrl = MODULE_PATH;
}
~~~
$name为@或者MODULE_NAME,获取对应模块目录。
`elseif (in_array($name, ['traits', 'think', 'behavior']))`
$name为traits,think,behavior等根命名空间,获取对应目录
`elseif (APP_NAMESPACE == $name) `
$name为应用命名空间,获取应用目录
`elseif (is_dir(EXTEND_PATH . $name))`
$name为框架扩展目录,获取扩展目录
~~~
else {
$baseUrl = APP_PATH . $name . DS;
}
~~~
$name为应用的$name的目录
~~~
elseif (substr($baseUrl, -1) != DS) {
$baseUrl .= DS;
}
~~~
$baseUrl参数存在,则解析为$baserUlr目录
`$filename = $baseUrl . $class . $ext;`
根据$baseUrl,$class,$ext合成目标文件名
~~~
if (is_file($filename)) {
if (APP_DEBUG && IS_WIN && false === strpos(realpath($filename), $class . $ext)) {
return false;
}
include $filename;
return true;
}
~~~
对应目标文件存在,加载对应目标文件。
## 3 加载器框架示例
~~~
thinkphp\start.php
Loader::register();
if (isset($mode['namespace'])) {
Loader::addNamespace($mode['namespace']);
}
if (isset($mode['alias'])) {
Loader::addMap(is_array($mode['alias']) ? $mode['alias'] : include $mode['alias']);
}
~~~
~~~
thinkphp\library\think\App::run()
if (!empty($config['root_namespace'])) {
Loader::addNamespace($config['root_namespace']);
}
~~~
~~~
thinkphp\library\think\App::initModule()
if (is_file($path . 'alias' . EXT)) {
Loader::addMap(include $path . 'alias' . EXT);
}
~~~
- 更新记录
- 概述
- 文件索引
- 函数索引
- 章节格式
- 框架流程
- 前:章节说明
- 主:(index.php)入口
- 主:(start.php)框架引导
- 主:(App.php)应用启动
- 主:(App.php)应用调度
- C:(Controller.php)应用控制器
- M:(Model.php)数据模型
- V:(View.php)视图对象
- 附:(App.php)应用启动
- 附:(base.php)全局变量
- 附:(common.php)模式配置
- 附:(convention.php)全局配置
- 附:(Loader.php)自动加载器
- 附:(Build.php)自动生成
- 附:(Hook.php)监听回调
- 附:(Route.php)全局路由
- 附:(Response.php)数据输出
- 附:(Log.php)日志记录
- 附:(Exception.php)异常处理
- 框架工具
- 另:(helper.php)辅助函数
- 另:(Cache.php)数据缓存
- 另:(Cookie.php)cookie操作
- 另:(Console.php)控制台
- 另:(Debug.php)开发调试
- 另:(Error.php)错误处理
- 另:(Url.php)Url操作文件
- 另:(Loader.php)加载器实例化
- 另:(Input.php)数据输入
- 另:(Lang.php)语言包管理
- 另:(ORM.php)ORM基类
- 另:(Process.php)进程管理
- 另:(Session.php)session操作
- 另:(Template.php)模板解析
- 框架驱动
- D:(\config)配置解析
- D:(\controller)控制器扩展
- D:(\model)模型扩展
- D:(\db)数据库驱动
- D:(\view)模板解析
- D:(\template)模板标签库
- D:(\session)session驱动
- D:(\cache)缓存驱动
- D:(\console)控制台
- D:(\process)进程扩展
- T:(\traits)Trait目录
- D:(\exception)异常实现
- D:(\log)日志驱动
- 使用范例
- 服务器与框架的安装
- 控制器操作
- 数据模型操作
- 视图渲染控制
- MVC开发初探
- 模块开发
- 入口文件定义全局变量
- 运行模式开发
- 框架配置
- 自动生成应用
- 事件与插件注册
- 路由规则注册
- 输出控制
- 多种应用组织
- 综合应用
- tp框架整合后台auto架构快速开发
- 基础原理
- php默认全局变量
- php的魔术方法
- php命名空间
- php的自动加载
- php的composer
- php的反射
- php的trait机制
- php设计模式
- php的系统时区
- php的异常错误
- php的输出控制
- php的正则表达式
- php的闭包函数
- php的会话控制
- php的接口
- php的PDO
- php的字符串操作
- php的curl
- 框架心得
- 心:整体结构
- 心:配置详解
- 心:加载器详解
- 心:输入输出详解
- 心:url路由详解
- 心:模板详解
- 心:模型详解
- 心:日志详解
- 心:缓存详解
- 心:控制台详解
- 框架更新
- 4.20(验证类,助手函数)
- 4.27(新模型Model功能)
- 5.4(新数据库驱动)
- 7.28(自动加载)