tp5.1自动加载机制

摘要:
在第85行之后,确定是否有composer文件夹以及是否有自动加载_ static.php文件必须存在,因为下载版本在5.1版之后不再在php官方网站上可用,并且仅支持通过composer下载。该文件是通过执行tp5.1命令行:phpthinkoptize:autoload生成的。摘要1。TP5.1根据规范的第一步自动加载类文件并查找根目录应用程序;根目录hinkphplibraryhink;根目录hinkphplibraryrails;根目录vendoropthink/think-installer/src;确定这四个文件夹下是否有类文件。

前言

    最近在学习TP5.1.37 框架内核,想把自己所学到的写下来,这样可以检测自己到底学到了多少,理解了多少。写的有不对的地方或者有不严谨的地方,还望大佬指正,谢谢。

正文

index.php 入口文件引入自动加载类Loader

tp5.1自动加载机制第1张  tp5.1自动加载机制第2张

 TP5.1入口文件引入加载了base.php文件,然后base.php文件中载入了Loader.php类,并且执行了Loader::register() 静态方法,我们来看看register方法内部都执行了什么。

 2. Loader类中register静态方法

tp5.1自动加载机制第3张

tp5.1自动加载机制第4张

(1)此方法中第一行,也就是第79行执行了php内置函数 spl_autoload_register() ,此函数的第一个参数接受一个匿名函数,或者回调方法,作用是 每当php调用了不存在的类的话就会执行此函数中的回调函数,且携带一个参数,值是引入的未存在的带命名空间的类名(如果有命名空间),如:在base.php中20行注册异常机制,那么这时携带的参数值是:thinkError。

(2)继续往下看,Loader类中81行是获得本项目的绝对路径,如:D:softwarephpstudyPHPTutorialWWW estTP5 p5_1 。82行获得vender目录下composer文件夹的绝对路径。

(3)85行后面,判断是否存在composer文件夹,是否存在autoload_static.php 文件,因为5.1版本后,php官网不再提供下载版本,只支持通过composer下载,所以这个文件一定是存在的。然后加载了这个类文件。

(4)88行执行了 get_declared_classes() 函数,此函数功能是获取由当前脚本中已定义类的名字组成的数组(包括自己引入的类,和php内置的一些类)。然后89行取出此数组中最后一个元素,也就是刚刚引入的autoload_static.php中的类,返回值是:ComposerAutoloadComposerStaticInit3ec0ccb9b30037c3270e4e4566239878

(5)91行,循环将刚才获得到的类中 成员属性 复制到本类Loader中, 在商法的类中存在两个静态成员属性:$prefixLengthsPsr4、$prefixDirsPsr4。形式如下图:
tp5.1自动加载机制第5张      tp5.1自动加载机制第6张

这两个成员属性是根据psr-4规范规则 而生成,可自行百度了解。这里将成员属性复制到本类后,后面加载文件时查找类的文件路径会用到,下面再讲。

(6)101行,注册think和tratis两个两个文件夹路径,调用self::addNamespace方法,主要做的事情就是将这两个命名空间、文件路径以psr-4规范形式 加入到上面所提的两个成员属性中$prefixLengthsPsr4、$prefixDirsPsr4。$prefixLengthsPsr4规则:将命名空间首字母当做第一维数组的键,将命名空间当做第二维数组的键,将此命名空间字符串长度当做第二维数组的值。$prefixDirsPsr4规则:将命名空间当做第一维数组的键,将对应的文件绝对路径当做第二维数组的值,第二位数组的键是自增的索引值。此时本类中的静态成员属性$prefixLengthsPsr4、$prefixDirsPsr4的值如下图:
tp5.1自动加载机制第7张

 tp5.1自动加载机制第8张

(7)106行加载类库映射文件,它会查找项目根目录下 untimeclassmap.php文件,将此文件中的一维数组值赋值到本类成员属性$classMap。这个文件是通过执行tp5.1命令行命令:php think optimize:autoload 生成的。生成的文件中包含了所有将要引入的类的 类名与文件绝对路径 的映射,此文件会提高寻找类文件的效率,一般项目完成时生成,如果后续有新建的类的话,此文件需要重新生成才能寻找到新的类文件。后面会讲到为何会提高加载类的效率。默认是没有此文件的。

(8)此方法的最后一行111行,自动加载extend目录,调用self::addAutoLoadDir()方法,做的事情是:将项目根目录下的extend目录绝对路径放到 成员属性 $fallbackDirsPsr4中。

3.  Loader::autoload自动加载时执行的方法

上面说到 spl_autoload_register()函数,如果调用不存在的类时将执行此函数中的第一个参数方法。那么将调用本类中的autoload方法。此方法代码:

tp5.1自动加载机制第9张

 上面说了,此方法的参数$class的值的带有命名空间的类名,119行判断本类中的成员属性$classAlias中是否存在此类名,如果存在,则将此类名设置别名,开始此属性值是空数组。继续往下,调用了self::findFile方法并将类名当做参数传入,返回$file值,下方130行引入此文件。我们来看看findFile方法做了哪些事情:
tp5.1自动加载机制第10张

 tp5.1自动加载机制第11张

(1)143行,首先判断成员属性$classmap中是否存在此类名的键,如果存在则直接返回。我们上方说到此成员属性值是执行tp5.1命令行命令生成的,所以生成文件后就不再往下执行 循环判断文件是否存在,直接返回文件路径,所以可以提高文件查找效率。

(2)152行if中执行的逻辑是根据psr-4规范查找类文件,具体是这样:取出这个带有命名空间类的第一个字母,判断成员属性$prefixLengthsPsr4是否存在此首字母的键值,然后循环这个键值,判断命名空间有没有是否存在$prefixLengthsPsr4二维的键,如果存在,根据$prefixDirsPsr4属性取出命名空间对应的绝对路径,然后拼接文件名,判断文件是否存在,如果存在则返回文件的绝对路径。

(3)165行下,循环$fallbackDirsPsr4属性下所有值拼接文件名,返回绝对路径并判断文件是否存在,若存在则返回。

(4)172行下是根据psr-0规则判断文件是否存在并返回,跟上方的psr-4异曲同工。

总结
1. TP5.1 自动加载类文件,根据规范第一步查找 根目录application;根目录 hinkphplibrary hink;根目录 hinkphplibrary raits;根目录vender opthink/think-installer/src;判断这四个文件夹下有没有存在类文件。

2. 第二步查找 根目录vender 目录下是否存在此文件。

3. 在上方五个 文件夹 下建类时,引入对应目录下的命名空间就可以自动加载,如果有新建文件夹,在新文件夹下建类文件时,引入对应目录下的命名空间 并且 拼接文件夹的名字 也可以实现自动加载。如:  appindexcontroller; vender est;

4. 有同学会有 将别人的 vender目录下的扩展包直接复制到自己的vender目录下,这样会报错不能自动引入的,如果想将复制来的包实现自动引入还需 根据规则 修改vendercomposerautoload_static.php类中的属性值,或者把对方的这个类文件也同时复制过来。

扩展
如果想实现自己定义的文件夹下的文件自动加载:如在根目录下新建了文件夹vender2

1. 在 入口文件index.php 引入base.php文件之后,加入:Loader::addAutoLoadDir(dirname(__DIR__).DIRECTORY_SEPARATOR.'vender2');

2. 根据psr-4规则将信息添加进vendercomposerautoload_static.php类中的属性值。(不推荐)

免责声明:文章转载自《tp5.1自动加载机制》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇执行一个外部程序并等待他的结束linux 查看并对外开放端口(防火墙拦截处理)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

crossdomain.xml跨域配置文件的安全注意事项

零、绪论: 对WEB中的FLASH确实了解不多,对程序中的跨域配置也了解不多,这是自己以前写的一篇笔记,到现在也还了解不深,勉强记下来罢了,备忘。 一、什么是crossdomain.xml?这是一个flash在跨域传输请求数据时要遵循的一个规则配置文件。例如a.com中swf文件要请求b.com中的数据,要检查该文件,如不存在则一律禁止跨域数据传输,如果存...

Jar包版本查看方法

原文:https://blog.csdn.net/u011287511/article/details/66973559 打开Java的JAR文件我们经常可以看到文件中包含着一个META-INF目录, 这个目录下会有一些文件,其中必有一个MANIFEST.MF,这个文件描述了该Jar文件的很多信息,下面将详细介绍MANIFEST.MF文件的内 容,先来看s...

每天一个linux命令(24):Linux文件类型与扩展名

Linux文件类型和Linux文件的文件名所代表的意义是两个不同的概念。我们通过一般应用程序而创建的比如file.txt、file.tar.gz ,这些文件虽然要用不同的程序来打开,但放在Linux文件类型中衡量的话,大多是常规文件(也被称为普通文件)。 一. 文件类型 Linux文件类型常见的有:普通文件、目录文件、字符设备文件和块设备文件、符号链接文件...

go第三方日志系统-seelog-Basic sections

https://github.com/cihub/seelog 文档学习:https://github.com/cihub/seelog/wiki 1.安装: go get github.com/cihub/seelog 2.快速启动 Seelog的设计非常方便。它的默认配置和包级别的日志记录器是现成的,所以开始你只需要两行代码: package main...

ArcEngine10.0三维开发

该系统分为四个模块,分别是文件的操作、场景的浏览、点查询和矢量文件生成TIN。下面分别对这四个模块做详细介绍。 文件操作。该模块包括打开工程文件(打开sxd文件)、打开栅格文件(打开Raster文件)和保存图片文件。所用到的控件有:SceneControl控件(用于显示打开的工程文件和栅格文件)、 Button控件、OpenFileDialog控件、Sa...

【H5】15 表单 其四 数据发送

一旦在客户端上验证了表单数据,就可以提交表单了。 并且,由于我们在上一篇文章中介绍了验证,因此我们准备提交! 本文着眼于用户提交表单时会发生什么—数据将流向何处,以及到达表单后如何处理? 我们还将研究与发送表单数据相关的一些安全问题。 先决条件: 基本的计算机知识,对HTML的理解以及HTTP和服务器端编程的基本知识。 目的: 了解提交表单数据...