magento2的自動加載要理解三個概念,分別是php
類名: 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中找,這裏會有一個問題,就是效率問題ubuntu
\Magento\Framework\Autoload\AutoloaderRegistry
它只有兩個方法,註冊registerAutoloader和獲取getAutoloader自動加載器,在magento中事實上只有一個類自動加載器能夠註冊和獲取,就是\Magento\Framework\Autoload\ClassLoaderWrapper
這樣的話,能夠在任何地方\Magento\Framework\Autoload\AutoloaderRegistry::getAutoloader()->addPsr4('命名空間','替換命名空間的絕對路徑')
在應用中只需註冊一次,任何地方能夠調用數組
它只有一個靜態方法populateMappings(類自動加載器容器, 目錄列表對象)
,它主要是處理生成的代碼,也就是/var/www/jihuizhenghao/store/generated/code
中的代碼,分別加到psr4,psr0和includePath中保證這裏面的類能夠正常使用\Magento\Framework\App\Bootstrap::populateAutoloader
就是調用上面的方法,只是將這個方法植入到了Bootstrap中緩存