第一部分是引入自動加載配置文件
1.入口文件:autoload.php
里面沒什么東西,就是導入ComposerAutoloader主題文件,一般由一個復雜的名字,不過不用擔心就是機器隨機生成的一個碼而已,就是普通的一個類,名字比較長了。
require_once __DIR__ . '/composer/autoload_real.php'; return ComposerAutoloaderInitd0a5721608b46fc86f3b980fb0cea37d::getLoader();
2.自動加載主題文件:ComposerAutoloaderInitd0a5721608b46fc86f3b980fb0cea37d
getLoader(){.....}
這個就是獲得自動加載的主方法,這個有點像代加工廠、里面其實只是組裝了下,實際的部件在別的類(后面會提到的ClassLoader類),接下來說說getLoader方法做了哪些代加工
- 把實際干活的小工招進廠->
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
- 判斷了下PHP版本 如果版本大於5.6 就使用閉包綁定的方式去進行綁定自動加載的配置、需要注意的是,這些內容其實都是composer dump-autoload命令生成的 所以修改了composer.json后一定要執行下該命令。下面的代碼段就是給各種psr規則都設置進私有變量,閉包居然還可以這么直接搞好犀利的趕腳
return \Closure::bind(function () use ($loader) { $loader->prefixLengthsPsr4 = ComposerStaticInitd0a5721608b46fc86f3b980fb0cea37d::$prefixLengthsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInitd0a5721608b46fc86f3b980fb0cea37d::$prefixDirsPsr4; $loader->prefixesPsr0 = ComposerStaticInitd0a5721608b46fc86f3b980fb0cea37d::$prefixesPsr0; }, null, ClassLoader::class);
- 如果版本小於5.6就使用原始點的方法,通過setxxx來一個個進行設置自動加載的配置,和上面實現的功能其實一樣的,但是代碼量就大很多了
$map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { $loader->set($namespace, $path); } $map = require __DIR__ . '/autoload_psr4.php'; foreach ($map as $namespace => $path) { $loader->setPsr4($namespace, $path); } $classMap = require __DIR__ . '/autoload_classmap.php'; if ($classMap) { $loader->addClassMap($classMap); }
- 最后把loader類注冊一下
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
第二部分是如何通過類名找到該文件並引入
- 入口方法:ClassLoader.php中的loadClass(),尋找順序是 先classMap里找 再PSR4 PSR0 找
// class map lookup if (isset($this->classMap[$class])) { return $this->classMap[$class]; } if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { return false; } if (null !== $this->apcuPrefix) { $file = apcu_fetch($this->apcuPrefix.$class, $hit); if ($hit) { return $file; } } $file = $this->findFileWithExtension($class, '.php'); // Search for Hack files if we are running on HHVM if (false === $file && defined('HHVM_VERSION')) { $file = $this->findFileWithExtension($class, '.hh'); } if (null !== $this->apcuPrefix) { apcu_add($this->apcuPrefix.$class, $file); } if (false === $file) { // Remember that this class does not exist. $this->missingClasses[$class] = true; } return $file;