composer
載入檔案
autoload.php
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitc8e7e2ff9618f4a7666639dbd0c65a25::getLoader();
在 autoload.php
檔案中通過 require_once
引入autoload_real.php
檔案, 在呼叫 ComposerAutoloaderInitc8e7e2ff9618f4a7666639dbd0c65a25::getLoader();
獲取載入器
autoload_real.php
getLoader
方法
- 判斷是否載入器是否已經存在, 載入器存在就返回
if (null !== self::$loader) {
return self::$loader;
}
- 通過
spl_autoload_register
呼叫自身loadClassLoader
方法
spl_autoload_register(array('ComposerAutoloaderInitc8e7e2ff9618f4a7666639dbd0c65a25', 'loadClassLoader'), true, true);
loadClassLoader
方法中驗證傳遞$class
變數是否等於Composer\Autoload\ClassLoader
, 相等的話使用require
引入ClassLoader
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
- 通過
loadClassLoader
方法中引入的ClassLoader
類來建立載入器
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
- 通過
spl_autoload_unregister
登出已經引入的類
spl_autoload_unregister(array('ComposerAutoloaderInitc8e7e2ff9618f4a7666639dbd0c65a25', 'loadClassLoader'));
- 判斷當前
php
版本和運許環境
PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
- 使用
PHP_VERSION_ID
判斷當前php
版本 - 使用
HHVM_VERSION
判斷是否已經定義, 存在代表是當前執行環境是HHVM
- 判斷
zend_loader_file_encoded
方法是否存在, 存在呼叫該方法在取反
- 根據
$useStaticLoader
狀態判斷
$useStaticLoader
為true
引入 autoload_static.php
檔案, 呼叫 ComposerStaticInitc8e7e2ff9618f4a7666639dbd0c65a25
類中 getInitializer
靜態方法獲取閉包函式, 在使用 call_user_func
呼叫閉包方法
require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitc8e7e2ff9618f4a7666639dbd0c65a25::getInitializer($loader));
在 getInitializer
方法中註冊了, 名稱空間($prefixLengthsPsr4
), 名稱空間路徑($prefixDirsPsr4
), $prefixesPsr0
, 類檔案對映($classMap
)
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitc8e7e2ff9618f4a7666639dbd0c65a25::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitc8e7e2ff9618f4a7666639dbd0c65a25::$prefixDirsPsr4;
$loader->prefixesPsr0 = ComposerStaticInitc8e7e2ff9618f4a7666639dbd0c65a25::$prefixesPsr0;
$loader->classMap = ComposerStaticInitc8e7e2ff9618f4a7666639dbd0c65a25::$classMap;
}, null, ClassLoader::class);
}
$useStaticLoader
為false
手動引入檔案和註冊
$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);
}
- 呼叫載入器的
register
方法
$loader->register(true);
register
方法這個放在後面說, 放在這裡會影響內容
- 引入自動載入檔案
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInitc8e7e2ff9618f4a7666639dbd0c65a25::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
判斷 $useStaticLoader
的狀態來選擇檔案載入方式
- 註冊載入檔案到
$GLOBALS
全域性變數中
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequirec8e7e2ff9618f4a7666639dbd0c65a25($fileIdentifier, $file);
}
迴圈呼叫 composerRequirec8e7e2ff9618f4a7666639dbd0c65a25
方法
function composerRequirec8e7e2ff9618f4a7666639dbd0c65a25($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
}
}
composerRequirec8e7e2ff9618f4a7666639dbd0c65a25
方法是否已經引入, 沒有引入先入檔案在賦值到 $GLOBALS
全域性變數中
- 最後返回載入器
ClassLoader.php
register
方法
使用 spl_autoload_register
呼叫自己 loadClass
方法載入類
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}
loadClass
方法
通過 findFile
載入 $class
檔案路徑, 通過 includeFile
方法載入檔案
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
}
includeFile
方法
使用 include
引入檔案
function includeFile($file)
{
include $file;
}
findFile
方法
- 使用
classMap
對映返回檔案
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
classMapAuthoritative
和missingClasses
判斷是否返回false
classMapAuthoritative
目前也清楚是幹嘛的missingClasses
判斷這個是否為缺失狀態
apcuPrefix
不為null
, 使用apcu_fetch
獲取檔案
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
- 使用
findFileWithExtension
查詢檔案
- 查詢
.php
檔案 或者.hh
檔案
$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');
}
- 如果
apcuPrefix
不為null
, 使用apcu_add
把檔案新增到快取中
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
- 如果檔案不存在, 標記為缺失狀態
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結