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,运行如下:

可见$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’文件。

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

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

解析后得到 $prefixLengthsPsr4为:

$prefixDirsPsr4为:

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

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

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

有点复杂,以后再看!

命名空间自动加载

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

// 解析命名空间

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定义:

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

所以$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);)。简易流程如下所示:

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

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标准官网。

时间: 2024-11-25 16:29:04

TP5代码学习笔记:Loader的相关文章

<第一行代码>学习笔记1.09

一.四大组件 Activity,Service,Broadcast Receiver,Content Provider. 二.搭建开发环境 三.自动创建android项目 1.创建项目  file---new---android application project application name:Hello World project name:HelloWorld package name:com.test.helloworld 2.创建活动 勾选create activity会创建模板

Android第一行代码学习笔记二---在活动中使用Toast

Toast:是Android系统提供的一种非常好的提醒方式,在程序中可以使用它将一些短小的信息通知给用户,这些信息会在一段时间后自动消失,并且不会占用任何屏幕空间. 首先需要定义一个弹出Toast触发点,接着笔记一的程序,正好上面有个按钮,我们就点击这个按钮的时候弹出来一个Toast,在onCreate()方法中添加如下代码: protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceStat

Android第一行代码学习笔记六---Intent向活动传递数据

@1.向下一个活动传递数据: Intent提供了一系列putExtra()方法的重载,可以把我们想要传递的数据暂存在Intent中,启动了另一个活动后,只需把这些数据再从Intent中取出就可以了,比如firstActivity中有一个字符串要传递到secondActivity中,修改firstActivity中按钮点击事件,代码可以这样编写: button.setOnClickListener(new View.OnClickListener() { public void onClick(V

APM代码学习笔记

libraries目录 传感器 AP_InertialSensor 惯性导航传感器 就是陀螺仪加速计 AP_Baro 气压计 居然支持BMP085 在我印象中APM一直用高端的MS5611 AP_Compass 指南针 AP_GPS GPS定位 还有些飞行姿态的 AP_ARHS 姿态解算 输出Roll Yaw Pitch AP_AttitudeControl 姿态控制 APM飞这么稳就靠它了 硬件抽象层 AP_HAL 头文件 AP_HAL_AVR APM2.X时代的板子 ATMega2560处理

Head First Python(如何向PYPI发布你的代码)学习笔记

Head  First  Python(如何向PYPI发布你的代码) 当我们编写好的一个完美的python程序或者一个好的项目程序时,那时作为程序猿的我们是如何的激动啊,在那激动的时刻如何与他人分享我们胜利的果实呢?看这里~哈哈 为了共享这个模块,需要将它发布出去,在python中,所谓发布(distribution)是指一个文件集合,将这些文件联合到一起允许你构建,打包和发布你的模块,一旦发布,就可以 把模块先安装到你的本地python上,还有就是可以把你的代码上传到PYPI与全世界共享你的代

1.JAVA中使用JNI调用C++代码学习笔记

Java 之JNI编程1.什么是JNI? JNI:(Java Natibe Inetrface)缩写. 2.为什么要学习JNI?  Java 是跨平台的语言,但是在有些时候仍然是有需要调用本地代码 (这些代码通常是由C/C++编写的). Sun公司提供的JNI是Java平台的一个功能强大的接口.这个JNI接口提供了Java与操作系统本地代码互相调用的功能.(即java调用C++代码) 最简单的Java调用C/C++代码步骤 1.创建TestNativeCode工程,新建cn.itcast包,新建

Android第一行代码学习笔记七---活动的生命周期

@1.返回栈 Android中的活动是可以层叠的,我们每启动一个新的活动,就会覆盖在原活动之上,然后点击Back键就会销毁最上面的活动,下面一个活动就会重新显示出来. Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也被称为返回栈(Back Stack).栈是一种后进先出的数据结构,在默认情况下,每当我们启动了一个新的活动,它会在返回栈中入栈,并处于栈顶的位置.而当我们按下Back键或调用finish()方法去销毁一个活动时,处于栈顶的活动会出栈,

hog特征原理详解及matlab代码学习笔记

1.HOG特征: 方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子.它通过计算和统计图像局部区域的梯度方向直方图来构成特征.Hog特征结合SVM分类器已经被广泛应用于图像识别中,尤其在行人检测中获得了极大的成功.需要提醒的是,HOG+SVM进行行人检测的方法是法国研究人员Dalal在2005的CVPR上提出的,而如今虽然有很多行人检测算法不断提出,但基本都是以HOG+SVM的思路为主. (1)主

Android第一行代码学习笔记三---在活动中使用Menu

在活动中使用Menu: 如果你活动中大量的菜单需要显示,这个·时候·界面·设计就会比较尴尬,Android给我们提供了一种方式,可以让菜单都能得到展示的同时,还能不占用任何空间.· res目录下新建一个menu文件夹,右击res目录->New->Directory,输入文件名menu,点击OK,接着在这个文件夹下.新建一个菜单文件,右击menu文件夹->New->Menu resource file.文件名输入main. 打开文件main.xml,输入如下代码: <?xml