1

magento2的自动加载要理解三个概念,分别是

  1. 自动加载器注册商,它是用来注册自动加载器用的,在应用的任何地方可以通过::getAutoloader()获取自动加截器
  2. magento自动加载器,它是composer自动加载器的代理,它只有6个public方法,不是继承composer加载器,是封装了composer加载器
  3. 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\ClassLoaderWrapperComposer\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中


advance100
599 声望80 粉丝

0he1.com在线课堂


引用和评论

0 条评论