tp5 Loader.php,TP5代码学习笔记:Loader

自动加载Loader类

一.概述

系统会调用Loader::register()方法注册自动加载,在这一步完成后,所有符合规范的类库(包括Composer依赖加载的第三方类库)都将自动加载。

系统的自动加载由两个部分组成:

1.注册系统的自动加载方法\think\Loader::autoload

2.注册Composer自动加载(符合Composer规范即可)

一个类库的自动加载检测顺序为:

1.是否定义类库映射;

2.Composer自动加载检测;

3.是否为注册的命名空间;

4.检测EXTEND_PATH目录下的扩展类库;

如果检测到以上任何一处,则按照PSR-4命名规范自动加载。

可以看到,定义类库映射的方式是最高效的。

二.autoload类

在Loader::autoload($class);中打印出$class,运行如下:

infodetail-1474480.html

infodetail-1474480.html

infodetail-1474480.html

可见$class为带命名空间的类名。

检测命名空间别名:有没有自动加载?

比如定义了一个类 kukiiu/Upload。给他定义一个命名空间别名org,这样我使用org/Upload类,就会用kukiiu/Upload类重新定义一个org/Upload类。

定义命名空间别名方法:

1.\think\Loader::addNamespaceAlias(‘org‘,‘kukiiu‘);

检查是否定义类库映射

打印出$map可看到里面的每项元素如下所示:

["think\App"]=> string(45) "F:\hwphp\study\thinkphp\library\think\App.php"

定义了映射后,在直接使用该类时就会去搜索定义给出的文件路径名,然后加载该文件。

在mode/common.php中定义了很多常用的类映射。

定义映射方法:

1.\think\Loader::addMap(‘test‘,APP_PATH.‘index\controller\Test.php‘);

dump(class_exists(‘test‘));

2.mode/common.php的alias是不是添加到map中?

Composer自动加载

执行composer install后,会在thinkphp/vendor下创建依赖文件。

1.tp在初始化时解析vendor/composer下的自动加载机制Loader::registerComposerLoader()。

a) 加载PSR-0规范的‘composer/autoload_namespaces.php’文件。

infodetail-1474480.html

解析后得到 self::$prefixesPsr0为:

infodetail-1474480.html

b) 加载PSR-4规范的‘composer/autoload_psr4.php‘文件。

infodetail-1474480.html

解析后得到 $prefixLengthsPsr4为:

infodetail-1474480.html

$prefixDirsPsr4为:

infodetail-1474480.html

c) 加载类映射文件(跟tp的类映射相同):‘composer/autoload_classmap.php‘。

d) 直接加载类文件。。。‘composer/autoload_files.php‘

2.在查找类时使用Loader::findFileInComposer()查看是否是composer下的类。

有点复杂,以后再看!

命名空间自动加载

没设置类映射,基本都是通过这里加载的类。打印出进入命名空间自动加载的类看看:

infodetail-1474480.html

// 解析命名空间

list($name, $class) = explode(‘\\‘, $class, 2);

将$class的第一个\前的值取出来:

如”app\index\controller\Index” 得到 $name=’app’ $class=’index\controller\Index’

if (isset(self::$namespace[$name])) {

// 注册的命名空间

$path = self::$namespace[$name];

} elseif (is_dir(EXTEND_PATH . $name)) {

// 扩展类库命名空间

$path = EXTEND_PATH . $name . DS;

} else {

return false;

}

$filename = $path . str_replace(‘\\‘, DS, $class) . EXT;

1.注册命名空间:

判断$name值在不在注册的$namespace中,这里的命名空间和概念命名空间不是同一个意思,容易搞混,这里注册的$namespace是一个标识,感觉叫命名空间前缀会好点,按PSR-0规范应该叫‘供应商vendor’,看mode/common.php可以看到,默认的一些$namespace定义:

infodetail-1474480.html

Loader::auotload()中打印出来$namespace如下所示:

infodetail-1474480.html

所以$namespace作用就是:将命名空间的第一个\前的值$class作为前缀,通过这个前缀找到它代表的路径。如app标识就代表了”F:\hwphp\study\application\”这个路径,之后如果在使用这个路径下的某个类,如

命名空间为\app\myclass\Test的类,就会将前缀替换为F:\hwphp\study\application\myclass\Test.php,从而加载该类文件。

例如:在tp框架里,每个模块都放在application下,而$namespace里有个’app’代表了这个路径,所以模块中的类只要命名空间符合tp规定的规范,就能够通过命名空间转为文件路径,如\app\index\controller\Index控制器,就能转换为”F:\hwphp\study\application\index\controller\Index.php”文件路径。

tp的命名空间自动加载类是基于PSR-4标准,定义的$namespace的key是命名空间前缀,value是类的基路径。在得到类的全名后:将命名空间前缀替换为基路径,将其余命名空间添加到其后,添加类名和后缀。和PSR-4不同的是,这里的命名空间前缀只有一层,免去了循环判断前缀的操作,(list($name,

$class) = explode(‘\\‘, $class, 2);)。简易流程如下所示:

infodetail-1474480.html

infodetail-1474480.html

infodetail-1474480.html

手动注册命名空间(标志)方法:

1.在应用入口文件中添加下面的代码:

\think\Loader::addNamespace(‘kukiiu‘,‘../extend/kukiiu/‘);

\think\Loader::addNamespace([

‘kukiiu‘=> ‘../extend/‘kukiiu‘/‘,

‘org‘ => ‘../extend/org/‘,

]);

2.在应用的配置文件中添加配置,系统会在应用执行的时候自动注册。

‘root_namespace‘ => [

‘my‘  => ‘../application/extend/my/‘,

]

3.在mode/common.php下$namespace下增加。

2.扩展类库命名空间:

thinkphp实现了自动注册命名空间(标识)机制,

把自己的类库包目录放入EXTEND_PATH目录(thinkphp/extend,可配置),就可以自动注册对应的命名空间(标识),

例如:在thinkphp/extend目录下面新增一个mylib目录,然后定义一个\mylib\Test类(类文件位于thinkphp/extend/mylib/Test.php),就可以直接调用new \mylib\Test();

在入口文件定义常量EXTEND_PATH,可以自定义扩展类库目录。

可以看出,tp的扩展类是基于PSR-0的自动加载标准。

其他函数:

...

参考资料:

1.http://www.php-fig.org/psr。PSR标准官网。

原文:http://blog.csdn.net/kuki_iu/article/details/50995367

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值