自动加载每个框架都有类自动加载机制,php使用require和include方法导入文件,当我们写Apublic类库,比如模型类,我们在使用模型类中的方法时,直接使用require或者include即可。但是当类似的公共文件很多的时候,每次导入都要用require和include,很麻烦,也不利于管理。PHP有一种机制叫做类的自动加载机制,tp框架通过spl_autoload_register()完成类的自动加载。自动加载是框架的灵魂。入口文件tp入口文件就是public目录下的index.php文件。在index.php中,首先通过require加载thinkphp目录下的start.php文件,然后在start.php中加载同目录下的base.php文件。index.php文件base.php中的start.php文件会加载Loader.php文件,loader.php是tp5自动加载的类库文件,是tp5的灵魂。Loader.php文件位于thinkphp/libarary/think目录中。Loader.php自动加载,tp5封装的底层基础类库。spl_auto_autoload_register()初步理解spl_auto_autoload_register()是自动加载文件的方法。现在我们创建一个和public同级的excise目录,然后创建一个test.php文件,在里面实例化一个Tests类,但是这个Tests类是不存在的,执行完肯定会报错。接下来,我们在excise目录下创建一个Tests类,并在类中写一个say方法。但是这样的话,也会报错。这时候就需要自动加载,自动加载是用spl_auto_autoload_register()来进行的。这样使用Tests.phptest.php后就不会报错了!执行结果:【属性深度分析】自动加载器深度分析在base.php文件中,加载Loader.php文件后,会注册并自动加载注册错误异常处理机制和配置文件。Loader.php注册方法A:使用了类似三元运算符的方法。如果在base.php注册自动加载的register方法中传递了有效参数,传递的参数就会被执行。如果不传入任何参数,就会执行Loader.php这个类的方法autoload。如果类不存在,autoload方法也会被执行。B:判断vendor目录下的composer是否为目录。C:判断php版本是否大于5.6.0。D:判断vendor/composer/autoload_static.php是否为文件。如果以上判断通过,则加载autoload_static.php文件。1:返回已定义类的名称数组。2:删除类数组中的最后一个元素。autoload_static.php,prefixLengthsPsr4属性$prefixLengthsPsr4是定义的参数,其中t和a是键,value是命名空间,命名空间的首字母作为键,后面跟一个数字代表命名空间的字符长度。两个斜线是转义,相当于斜线。~~~~prefixDirsPsr4属性中的红线可以忽略,代码没问题。$prefixDirsPsr4参数列出了每个命名空间对应的目录。比如think\对应thinkphp/library/think目录,app\对应应用目录。psr0和psr4是php的规范。当使用composer下载的插件时,会通过psr系列规范自动将对应的命名空间添加到上述两个参数中。下一步是注册名称空间定义。此时将prefixLengthsPsr4、prefixDirsPsr4、fallbackDirsPsr4中的think、behavior、traints放到addNamespace方法中:传入的$namespace参数为数组如下图,fallbackDirsPsr4属性:如果namespace为数组,则调用在foreach之后添加Psr4方法;如果不是数组,直接调用addPsr4方法。addPsr4():通过上面的分析,我们可以知道self::$prefixDirsPsr4[$prefix]不存在,所以按照中间的逻辑。接下来,加载类库映射文件。在项目目录文件夹下执行phpthinkoptimize:autoload命令生成classmap.php文件。它是一个类映射关系文件。addClassMap()方法判断$class是否为数组。如果是数组,将$class合并到$classMap中。如果不是数组,则将$class添加到$classMap中。然后载入extend目录,将extend路径载入$fallbackDirsPsr4[]。【类别名设置】深入解析自动加载Loader上面我们提到,当传递给register()方法的参数为空或者调用的类不存在时,就会执行autoload方法。autoload方法是设置类的别名。下面我们一步步分析里面的逻辑。A:$namesaceAlias参数是Loder中定义的命名空间别名数组。首先判断$namespace是否为空B:将$class的目录路径赋值给$namespaceC:判断$namespaceAlis[$namespace]是否为空D:然后将$class的类名添加到$namespacaAlis[的后面$namespace],然后赋值给$originalE:判断$original类是否存在。该类的别名。这是返回文件名。使用findFile函数查找classMap文件中是否存在这个文件。如果存在,它将返回并继续下一步。$logicalPathPsr4是通过将$class添加到.元素的键被分配给$first。然后判断$prefisLengthsPsr4[$first]是否存在,如果存在则进行foreach遍历,判断$class是否为$prefisLengthsPsr4[$first]中第一个位置的key,然后遍历判断$prefisLengthsPsr4[返回的值$first]是否是文件,如果是文件则返回。然后遍历$fallbackDirsPsr4,判断$logicalPathPsr4是否为$fallbackDirsPsr4中的文件。以上就是tp5自动加载的过程。这是我第一次写博客。
