Автор оригинала: David Wong.
Следуя второй статье жизненного цикла, вы можете быть уверены, что не будете случайно размещать статьи.
В первой статье мы упомянули сценарий ввода, в котором была зарегистрирована функция автоматической загрузки.
- По умолчанию у вас есть основа для автоматической загрузки и пространств имен. Если нет, см. эту статью об автоматической загрузке и пространствах имен для классов PHP
Автоматическая загрузка PHP Загружена Реализовано в классе, который находится в базе . php Введено в
//base .php // Load the Loader class require __DIR__ . '/library/think/Loader.php'; // Registration Autoloading Loader::register();
Здесь наша программа выполняет статические методы в загрузчике, который также является полным классом. регистрация() Мы входим Мы входим
Процесс выполнения метода Register ()
Автоматическая Загрузка Системы Регистрации
Этот метод слишком длительный. Давайте проанализируем это по крупицам.
// Registration System Autoloading
spl_autoload_register($autoload ?: 'think\Loader::autoload', true, true);Это делается для регистрации нашей функции автоматической загрузки. $автоматическая загрузка Эта переменная является передающим параметром. Учитывая, что вы можете реализовать свой собственный класс загрузки, TP позволяет вам реализовать свой собственный метод загрузки для легкого расширения.
Если вы не знаете об этой функции, пожалуйста, перейдите по ссылке в верхней части статьи, которая подробно описана.
Поддержка автоматической загрузки Композитора
$rootPath = self::getRootPath();
self::$composerPath = $rootPath . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR;
// Composer Autoloading Support
if (is_dir(self::$composerPath)) {
if (is_file(self::$composerPath . 'autoload_static.php')) {
require self::$composerPath . 'autoload_static.php';
// Get all classes currently loaded
$declaredClass = get_declared_classes();
$composerClass = array_pop($declaredClass);
foreach (['prefixLengthsPsr4', 'prefixDirsPsr4', 'fallbackDirsPsr4', 'prefixesPsr0', 'fallbackDirsPsr0', 'classMap', 'files'] as $attr) {
if (property_exists($composerClass, $attr)) {
self::${$attr} = $composerClass::${$attr};
}
}
} else {
self::registerComposerLoader(self::$composerPath);
}
}Для поддержки расширения composer, composer также регистрируется случайно при автоматической регистрации, чтобы облегчить вызов расширения.
Существует проблема с загрузкой переменных в autoload_static.php в память: Потому что имена классов в autoload_static.php файл всегда меняется, мы не можем получить фиксированное имя класса. (Например, имя класса в моей системе ComposerStaticInit5109814b18095308ffe89ba7a1be18df )
Ради требуйте себя::$composerPath . ' autoload_static.php'; Атрибуты загружаются в процесс, и здесь мы меняем форму.
Сначала загрузите все имена классов, загруженные в программу, а затем возьмите последнее имя класса, которое мы загрузили (то есть последнее в массиве).
$declaredClass = get_declared_classes(); $composerClass = array_pop($declaredClass);
Получите имя нашего класса, позвоните property_exists (класс$composer, $attr) Проверьте, существует ли указанное свойство в классе
Вопрос: Что представляет собой параметр composer_static?
What is the role of the following ('fallbackDirsPsr4','prefix DirsPsr4','fallbackDirsPsr4','prefixes Psr0','fallbackDirsPsr0','fallbackDirsPsr0','classMap','files'] as $attr) in foreach ('fallbackDirsPsr4','prefixesPsr0','fallbackDirsr0','Map','files')?Карта классов (сопоставление пространств имен)
public static $classMap = array (
'App\Http\Controllers\Auth\ForgotPasswordController'
=> __DIR__ . '/../..' . '/app/Http/Controllers/Auth/ForgotPasswordController.php',
'App\Http\Controllers\Auth\LoginController'
=> __DIR__ . '/../..' . '/app/Http/Controllers/Auth/LoginController.php',
'App\Http\Controllers\Auth\RegisterController'
=> __DIR__ . '/../..' ,
……
)Сопоставление полного имени прямого пространства имен с каталогом является простым и грубым, что также приводит к довольно большому массиву.
PSR 4 стандартный массив сопоставления пространств имен верхнего уровня:
public static $prefixLengthsPsr4 = array(
'p' => array (
'phpDocumentor\Reflection\' => 25,
),
'S' => array (
'Symfony\Polyfill\Mbstring\' => 26,
'Symfony\Component\Yaml\' => 23,
'Symfony\Component\VarDumper\' => 28,
...
),
...);
public static $prefixDirsPsr4 = array (
'phpDocumentor\Reflection\' => array (
0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src',
1 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src',
2 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src',
),
'Symfony\Polyfill\Mbstring\' => array (
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
),
'Symfony\Component\Yaml\' => array (
0 => __DIR__ . '/..' . '/symfony/yaml',
),
...)Стандартное сопоставление пространства имен верхнего уровня PSR 4 использует два массива. Первый-использовать первую букву пространства имен в качестве индекса префикса, а затем пространство имен верхнего уровня, но в конечном счете не путь к файлу, а длину пространства имен верхнего уровня. Почему?
Поскольку стандарт PSR 4 заменяет пространство имен верхнего уровня каталогом пространства имен верхнего уровня, важно получить длину пространства имен верхнего уровня.
Конкретно укажите роль этих массивов:
Если мы будем его искать Symfony\Polyfill\Mbstring\пример Это пространство имен получается путем сопоставления индекса префикса и строки.
'Symfony\Polyfill\Mbstring\' => 26,
В этой записи ключом является пространство имен верхнего уровня, а значением-длина пространства имен. Получите пространство имен верхнего уровня и перейдите $prefixDirsPsr4 Массив получает свой сопоставленный массив каталогов: (Обратите внимание, что может быть несколько каталогов сопоставления)
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
)Тогда мы можем использовать пространство имен Symfony\\Polyfill\\Mbstring\\пример Замените первые 26 символов каталогами __DIR__ . '/..' . '/symfony/polyfill-mbstring И мы получили это. __РЕЖИССЕР__ . '/..' . '/symfony/polyfill-mbstring/example.php Сначала убедитесь, что файл на диске существует, если нет, а затем перейдите. Если он не найден после обхода, загрузка завершается неудачно.
Примечание: Как веб-фреймворк, содержимое composer не должно быть связано с ThinkPHP, но поскольку дизайн собственного пакета фреймворка TP5 не полностью содержит composer, его значения атрибутов будут использоваться при регистрации для автоматической загрузки (только для вашего собственного понимания, если оно отличается от вашей точки зрения, приветствуется обсуждение).
Зарегистрированное определение пространства имен
// Registered namespace definition
self::addNamespace([
'think' => __DIR__,
'traits' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'traits',
]);
// Loading class library mapping files
if (is_file($rootPath . 'runtime' . DIRECTORY_SEPARATOR . 'classmap.php')) {
self::addClassMap(__include_file($rootPath . 'runtime' . DIRECTORY_SEPARATOR . 'classmap.php'));
}
// Auto-loading extension directory
self::addAutoLoadDir($rootPath . 'extend');Код, лежащий в основе этого, очень похож, сопоставляя все классы, которые необходимо использовать, с пространством Psr 4 В этой статической переменной. Нам будет удобно использовать пространства имен для вызовов.
// Loading class library mapping files
if (is_file($rootPath . 'runtime' . DIRECTORY_SEPARATOR . 'classmap.php')) {
self::addClassMap(__include_file($rootPath . 'runtime' . DIRECTORY_SEPARATOR . 'classmap.php'));
}Выполнить в коде TP5 php подумайте об оптимизации:автоматическая загрузка Карта классов. PHP-файл будет сгенерирован во время выполнения в виде файла.
return [
'app\index\controller\Index' => 'D:/app/tp5/application/' . 'index/controller/Index.php',
'think\App' => 'D:/app/tp5/thinkphp/library/' . '/think/App.php',
'think\Build' => 'D:/app/tp5/thinkphp/library/' . '/think/Build.php',
'think\Cache' => 'D:/app/tp5/thinkphp/library/' . '/think/Cache.php',
'think\Collection' => 'D:/app/tp5/thinkphp/library/' . '/think/Collection.php',
...
]Создайте файл сопоставления библиотеки классов, который будет во время выполнения Генерация в каталоге classmap.php Созданный файл сопоставления библиотеки классов сканирует библиотеки классов системного каталога и каталога приложений. После этого он может быть непосредственно использован для повышения производительности системы автоматической загрузки.
зарегистрироваться() Функция здесь, вероятно, является концом анализа. Здесь мы закончили регистрацию для автоматической загрузки.
Используйте автоматическую загрузку
Мы регистрируемся В этой статье мы определяем нашу функцию автоматической загрузки. Загрузчик::автозапуск() Метод. Мы попробуем бычий нож, в нашем base.php После того, как мы загрузим механизм автоматической загрузки, будет загружена наша обработка исключений.
// Load the Loader class require __DIR__ . '/library/think/Loader.php'; // Registration Autoloading Loader::register(); // Registration error and exception handling mechanism Error::register();
Ошибки в этом состоянии не существует, и все перейдет в наш метод автоматической загрузки и повторит попытку.
// Overall content of function
public static function autoload($class)
{
if (isset(self::$classAlias[$class])) {
return class_alias(self::$classAlias[$class], $class);
}
if ($file = self::findFile($class)) {
// Win environment is case-sensitive
if (strpos(PHP_OS, 'WIN') !== false && pathinfo($file, PATHINFO_FILENAME) != pathinfo(realpath($file), PATHINFO_FILENAME)) {
return false;
}
__include_file($file);
return true;
}
}Давайте разрежем фрагменты и проанализируем их по крупицам.
if (isset(self::$classAlias[$class])) {
return class_alias(self::$classAlias[$class], $class);
}Этот раздел предназначен для определения того, создали ли мы псевдоним этого класса, но, очевидно, мы его еще не установили.
if ($file = self::findFile($class)) {
// Win environment is case-sensitive
if (strpos(PHP_OS, 'WIN') !== false && pathinfo($file, PATHINFO_FILENAME) != pathinfo(realpath($file), PATHINFO_FILENAME)) {
return false;
}
__include_file($file);
return true;
}Файл поиска($класс) Если бы мы ранее кэшировали карту классов в папке времени выполнения, она бы вернулась напрямую. ((Вот почему кэширование карт классов повышает производительность.) Если кэширование отсутствует, он соответствует статическому массиву, который мы использовали для хранения отношений сопоставления. prefixDirsPsr4 , и Длина префикса SPSR4 Поиск каталога файлов может быть намного медленнее. Если нет, вернитесь к пустому. spl_autoload_регистр
Если он найден, устраните разницу между Linux и Windows в именах путей. (linux чувствителен к регистру, но win-нет.)
Основная проблема здесь заключается в том, что в среде Windows имена путей не указаны, поэтому мы переписываем пути к файлам в соответствии с правилами каталогов Linux.
Затем добавьте файлы нашего каталога.
Оригинал: “https://developpaper.com/analysis-of-thinkphp-5-1-source-code-2-automatic-loading-mechanism/”