magento2的自动加载要理解三个概念,分别是
- 自动加载器注册商,它是用来注册自动加载器用的,在应用的任何地方可以通过::getAutoloader()获取自动加截器
- magento自动加载器,它是composer自动加载器的代理,它只有6个public方法,不是继承composer加载器,是封装了composer加载器
- composer自动加载器,它才是所有自动加载器的核心
类名: Composer\Autoload\ClassLoader
文件: 项目根目录/vendor/composer/ClassLoader.php
Composer\Autoload\ClassLoader 对象(
// 第一步在classMap找,键为类名,值就是要导入的文件
classMap => Array(
ArithmeticError => /var/www/jihuizhenghao/store/vendor/composer/../symfony/polyfill-php70/Resources/stubs/ArithmeticError.php
...
less] => /var/www/jihuizhenghao/store/vendor/composer/../oyejorge/less.php/lessc.inc.php
)
// 第二步,如果classMapAuthoritative的值为真,就只在classMap中找,没找到就返回false,它就是一个开关,使用setClassMapAuthoritative(true)就开启这个功能,很少用到这个功能。
classMapAuthoritative =>
// 第二步,这里储存曾经找的类,但没有找到的放在这里,免得浪费时间多次寻找没有找到的类
missingClasses => Array(
[Zend\ServiceManager\PluginManagerInterface => 1
)
有关apcu扩展的安装参考 https://guides.wp-bullet.com/install-apcu-object-cache-for-php7-for-wordpress-ubuntu-16-04/
// 第三步:如果php安装并开启了apcu扩展(php_apcu.dll),且使用setApcuPrefix('缓存前缀')开启了,那么从缓存中读取,这样速度比较快
apcuPrefix =>
//第四步:PSR-4寻找
如类: Zend\ServiceManager\PluginManagerInterface,对应的文件是 Zend/ServiceManager/PluginManagerInterface.php,
01:看首字母(如Z)在prefixLengthsPsr4中有,有的话
02:获取类名的命令空间部分(最后一个\及前面的部分) 在prefixDirsPsr4中存在,在其对应的数组中找,值目录/类名.php,其实不是命令空间替换成其对应的路径
psr4前缀目录是一个关联数组,而psr4回调目录是一个一维索引数组,当首字母没有在psr4前缀长度中时,就会在回调目录中找,找法是路径+含命名空间的完全类名,
一般很少在回调中找,基本上都是在psr4前缀目录中找
psr4的设置方法是 set/addPsr4(false,'一个绝对目录'),设置是的psr4回调,很少用
set/addPsr4('命名空间\','一个用来替换命名空间的绝对目录'),第一个参数必须是以\结尾,开头没有\
prefixLengthsPsr4 => [
Z => [
Zend\View\ => 10
...
Zend\Captcha] => 13
]
...
A => [
Amazon\Payment\ => 15
AmazonPay\ => 10
]
]
prefixDirsPsr4 => Array(
phpDocumentor\Reflection\ => Array(
[0] => /var/www/jihuizhenghao/store/vendor/composer/../phpdocumentor/reflection-common/src
[1] => /var/www/jihuizhenghao/store/vendor/composer/../phpdocumentor/reflection-docblock/src
[2] => /var/www/jihuizhenghao/store/vendor/composer/../phpdocumentor/type-resolver/src
)
...
AmazonPay\ => Array(
[0] => /var/www/jihuizhenghao/store/vendor/composer/../amzn/amazon-pay-sdk-php/AmazonPay
)
)
fallbackDirsPsr4 => Array()
// 第五步:PSR-0寻找
类名是否含有\,如Zend\ServiceManager\PluginManagerInterface
prefixesPsr0 => Array(
Z => Array(
[Zend_] => Array(
[0] => /var/www/jihuizhenghao/store/vendor/composer/../magento/zendframework1/library
B => Array(
[Braintree] => Array(
[0] => /var/www/jihuizhenghao/store/vendor/composer/../braintree/braintree_php/lib
)
)
)
fallbackDirsPsr0 => Array(
[0] => /var/www/jihuizhenghao/store/vendor/composer/../../app/code
)
useIncludePath =>
)
类自动加载器二次封装
\Magento\Framework\Autoload\ClassLoaderWrapper
是Composer\Autoload\ClassLoader
类加载器的封装,后面只需要调用ClassLoaderWrapper中的addPsr4/addPsr0/setPsr4/setPsr0
方法,但这个封装器findFile的思路有一点改变,就是它不从classMap中找,这里会有一个问题,就是效率问题
类自动加载器注册商
\Magento\Framework\Autoload\AutoloaderRegistry
它只有两个方法,注册registerAutoloader和获取getAutoloader自动加载器,在magento中事实上只有一个类自动加载器可以注册和获取,就是\Magento\Framework\Autoload\ClassLoaderWrapper
这样的话,可以在任何地方\Magento\Framework\Autoload\AutoloaderRegistry::getAutoloader()->addPsr4('命名空间','替换命名空间的绝对路径')
在应用中只需注册一次,任何地方可以调用
Populator(暂翻译成居民)
它只有一个静态方法populateMappings(类自动加载器容器, 目录列表对象)
,它主要是处理生成的代码,也就是/var/www/jihuizhenghao/store/generated/code
中的代码,分别加到psr4,psr0和includePath中保证这里面的类可以正常使用\Magento\Framework\App\Bootstrap::populateAutoloader
就是调用上面的方法,只是将这个方法植入到了Bootstrap中
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。