保护私人版权,尊重他人版权。转载请注明出处并附带页面链接
本文主要来聊聊Laravel框架使用composer自动记载类的机制。
一、自动加载的类型
总的来说composer提供了几种自动加载类型
- classmap
- psr-0
- psr-4
- files
二、自动加载过程
入口文件autoload.php
1
require_once __DIR__ . '/../vendor/autoload.php';
里面就是直接导入ComposerAutoloader文件
1
2
3
4
5
6
7
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitd6090b535df29c04b3252807d8392e6a::getLoader();这里是composer自动生成的带了一串hash值的类名,应该只是为了防止类重名。
绑定自动加载的配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitd6090b535df29c04b3252807d8392e6a', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInitd6090b535df29c04b3252807d8392e6a', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitd6090b535df29c04b3252807d8392e6a::getInitializer($loader));
} else {
$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->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInitd6090b535df29c04b3252807d8392e6a::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequired6090b535df29c04b3252807d8392e6a($fileIdentifier, $file);
}
return $loader;
}通过类名找到该文件并引入,先在classmap里找再在psr-4找
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29public function findFile($class)
{
// 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;
}
三、composer对psr-4的处理
自动生成的psr-4配置文件在vendor/composer/autoload_psr4.php,返回了一个关联map,键是
使用psr-4的好处
- 减少了代码目录的深度
- 通过前缀快速找到映射目录提高了加载的效率