前面分析了file和classmap的加载方式,本篇介绍PSR-0和PSR-4的加载方式。
PSR标准
PSR-0自动加载
1.在composer.json同级目录下新建文件:\application\Controller\Test.php,内容如下:
2.修改composer.json文件,内容如下:
3.修改index.php,内容如下:
4.更新composer配置文件
运行命令:composer dump-autoload
5.执行index.php:php index.php,报错了,提示找不到:
原因为PSR-0会在application文件夹下去找\App\Controller\Test.php文件是否存在,存在则引入。但显然\application\App\Controller\Test.php文件并不存在。
解决办法:在application文件夹下新建一个App文件夹,然后把Test文件夹放进去就可以了。
PSR-4自动加载
PSR-4就简洁多了。
1.修改composer.json文件:
2.更新composer配置文件
运行命令:composer dump-autoload
3.执行index.php:php index.php,PSR-4会根据此路径:\application\Controller\Test.php找文件,存在则引入。跟PSR-0相比,就省略了App\。
自动加载流程分析
psr-0
当composer.json中指定的是PSR-0加载方式时,执行composer dump-autoload命令后,产生了如下变化:
1.autoload_namespaces.php
该文件返回的数组中,会增加一个元素:
内容为App对应的磁盘路径。
2.autoload_static.php
该文件新增了1个静态成员属性,$prefixesPsr0。
$prefixesPsr0用类全名的第一个字母来做分类,方便后续的快速搜索。值为类所在的磁盘路径。
psr-4
当执行composer dump-autoload命令后,产生了如下变化:
1.autoload_psr4.php
该文件返回的数组中,会增加一个元素:
内容为App对应的磁盘路径。
2.autoload_static.php
该文件新增了两个静态成员属性,$prefixLengthsPsr4和$prefixDirsPsr4。
$prefixLengthsPsr4用类全名的第一个字母来做分类,方便后续的快速搜索。
$prefixDirsPsr4为类所在的磁盘路径。
自动加载过程
当程序执行到需要加载类文件时,首先调用的是ClassLoader.php文件的loadClass方法。
该方法中通过findFile方法来查找类文件,如果找到了,就通过includeFile引入进来。findFile方法的内容如下:
该方法首先检查自身的classMap数组中是否包含有该类,如果有,直接返回。如果没有则执行到$this->findFileWithExtension方法中。
findFileWithExtension方法的代码如下:
可以看到,首先是按照PSR-4的标准,按类首字母进行循环,如果匹配到,则进一步匹配循环,如果找到类文件,则引入。如果按照PSR-4标准没有找到,则继续按PSR-0标准循环查找,如果找到类文件,则引入。