Рубрики
Uncategorized

Углубленный анализ принципа автоматической загрузки композитора

Автор оригинала: David Wong.

PHP был обновлен с версии 5.3. Пространства имен, функции, замыкания, интерфейсы, спецификации PSR и композиторы сделали PHP современным языком сценариев. Экосистема PHP развивалась, и появление composer полностью изменило способ создания PHP-приложений в прошлом. Мы можем смешивать и подбирать наиболее подходящие компоненты PHP в соответствии с требованиями приложения PHP. Конечно, он также извлекает выгоду из спецификации PSR.

  • Функция автоматической загрузки PHP
  • Спецификация PSR
  • Автоматический процесс загрузки композитора
  • Анализ исходного кода композитора

Происхождение функции автоматической загрузки PHP

В разработке PHP, если вы хотите ввести класс извне, вы обычно используете его включить и потребовать Метод для включения файла, определяющего этот класс. Это не большая проблема в маломасштабном развитии. Но в крупномасштабных проектах разработки использование этого подхода может вызвать некоторые неявные проблемы: если файл PHP должен использовать много других классов, то ему нужно много других классов. требовать/включать Заявление, поэтому это может быть Причиной пропусков возможно Включать ненужные файлы классов . Если большому количеству файлов необходимо использовать другие классы, должно быть кошмаром убедиться, что каждый файл содержит правильные файлы классов, и требовать или затуманивать затраты на высокую производительность.

PHP5 предоставляет решение этой проблемы, которое представляет собой Механизм автоматической загрузки классов . Механизм автоматической загрузки Это позволяет программам PHP автоматически включать файлы классов при использовании классов, а не все файлы классов с самого начала. включить Войти, этот механизм также называется Ленивая загрузка

  • Таким образом, функция автоматической загрузки дает несколько преимуществ:

    1. Нет необходимости перед использованием классов включать/требовать
    2. Только при использовании классов включить/требуется Файл, реализован ленивая загрузка Избегайте этого. включить/потребовать Избыточные файлы.
    3. Нет необходимости рассматривать возможность введения фактического адреса диска класса Он реализует разделение файлов логики и сущностей.

Функция автоматической загрузки PHP _autoload()

  • Начиная с PHP5, когда мы используем класс, если мы обнаруживаем, что он не загружен, мы автоматически запускаем функцию _autoload (), которая настроена в нашей программе, в которой мы можем загружать классы, которые нам нужны для использования. Вот простой пример:

  • В нашем простом примере мы просто добавляем расширение к имени класса. .class.php Создайте имя файла класса, а затем используйте require_once Загрузите его.

    Из этого примера мы видим, что _autoload должен сделать по крайней мере три вещи:

    1. Имя файла класса определяется в соответствии с именем класса.
    2. Определите путь к диску, на котором находится файл класса.
    3. Загружайте классы из файлов на диске в систему.
  • Третий шаг является самым простым и его нужно использовать только включить/потребовать Да. Чтобы выполнить первый и второй шаги, мы должны согласовать метод сопоставления имени класса и файла на диске во время разработки. Только таким образом мы сможем найти соответствующий файл на диске в соответствии с именем класса.
  • Когда требуется включить большое количество файлов классов, нам просто нужно определить соответствующие правила, а затем __autoload() В функции имя класса может быть сопоставлено с фактическим файлом на диске. ленивая загрузка Эффект
  • Если вы хотите узнать больше о процессе автоматической загрузки автозапуска, вы можете ознакомиться с информацией, приведенной в руководстве: Описание функции автоматической загрузки PHP

_ проблемы в функции автоматической загрузки ()

  • Если при реализации системы требуется много других библиотек классов, они могут быть написаны разными разработчиками, имена классов которых отличаются от фактических правил сопоставления файлов на диске. В настоящее время, если мы хотим реализовать автоматическую загрузку файлов библиотеки классов, мы должны Реализовать все правила сопоставления в функции _autoload () В этом случае __autoload() Функции могут быть очень сложными или даже невозможными для реализации. Это может в конечном итоге привести к __автозапуску() Функция очень громоздкая, даже если ее можно реализовать в настоящее время, это окажет большое негативное влияние на будущее обслуживание и эффективность системы.
  • Так в чем же возникает проблема? Возникает проблема. _ autoload () – это глобальная функция, которую можно определить только один раз Он недостаточно гибок, поэтому все логические правила, соответствующие имени класса и имени файла, должны быть реализованы в одной функции, что приводит к раздутой функции. Так как же решить эту проблему? Ответ заключается в том, чтобы использовать один из них. _ стек вызовов автоматической загрузки Различные отношения отображения записываются в разные _ функция автоматической загрузки Для перехода, а затем единая регистрация и единое управление, это введение PHP5 Автоматическая загрузка SPL

Автоматическая загрузка SPL

  • SPL-это аббревиатура стандартной библиотеки PHP. Это расширенная стандартная библиотека, представленная PHP 5, включающая функции, связанные с загрузкой spl, и интерфейсы или классы различных структур данных и итераторов. Функции, связанные с Spl_autoload, можно увидеть в PHP

Spl_autoload_register () – это стек вызовов _autoload, о котором мы упоминали выше. Мы можем зарегистрировать в этой функции многие из наших собственных функций автоматической загрузки (). Когда PHP не может найти имя класса, PHP вызовет стек, а затем вызовет пользовательскую функцию автоматической загрузки (), чтобы реализовать функцию автоматической загрузки. Если мы не введем никаких параметров в эту функцию, функция spl_autoload() будет зарегистрирована по умолчанию.

Спецификация, связанная с автоматической загрузкой, – PSR4. Прежде чем мы поговорим о PSR4, мы сначала представим стандарт PSR. Организацией по изобретению и внедрению стандарта PSR является PHP-FID, веб-сайт которой www.php-fig.org. Основанная в 2009 году несколькими разработчиками фреймворков с открытым исходным кодом, с тех пор было отобрано много других участников, хотя и не “официальных” организаций, но также представляющих небольшую часть сообщества. Цель организации состоит в том, чтобы унифицировать спецификации кодирования различных проектов с минимальными ограничениями и избежать трудностей развития программистов, которым мешают их собственные стили разработки. Так много людей придумали и обобщили PSR, который является аббревиатурой Рекомендации по стандартам PHP. На данный момент существует 14 наборов спецификаций PSR, из которых 7 были проголосованы и запущены. Использование заключается в следующем:

PSR-0 Стандарт автоматической загрузки (Заброшен, некоторые старые сторонние библиотеки все еще используются)

PSR-1 Основные стандарты кодирования

PSR-2 Мастер стилей кодирования

PSR-3 Интерфейс журнала

PSR-4 Улучшенная версия с автоматической загрузкой, Заменена PSR-0

PSR-6 Спецификация интерфейса кэша

Спецификация интерфейса сообщений PSR-7 HTTP

Конкретные и подробные спецификации можно увидеть в стандартных спецификациях PHP

Стандарт PSR 4

В конце 2013 года PHP-FIG запустил свою пятую спецификацию PSR-4.

PSR-4 указывает, как указать пути к файлам для автоматической загрузки определений классов, а также указывает расположение автоматически загружаемых файлов.

1) Полное имя класса должно иметь следующую структуру:

\ \ Пространства имен > Подпространства имен > Имена классов >

  • Полное имя класса Должно Иметь пространство имен верхнего уровня под названием “пространство имен поставщика”;
  • Полное имя класса Обязательно Имеет одно или несколько подпространств имен;
  • Полное имя класса Должно Иметь окончательное имя класса;
  • В полном имени класса Любая часть Для линии скольжения вниз нет особого значения.
  • Полное имя класса Конечно Он состоит из произвольных прописных и строчных букв.
  • Все имена классов Должны Учитываться с учетом регистра.

2) Загрузите соответствующий файл в соответствии с полным именем класса

  • В полном имени класса первый разделитель пространства имен удаляется, и одно или несколько последовательных пространств имен и подпространств впереди должны соответствовать по крайней мере одному “каталогу файловой базы” в качестве “префикса пространства имен”.
  • Пространства имен сразу после префикса пространства имен должны совпадать с соответствующим каталогом файловой базы, где разделитель пространства имен будет выступать в качестве разделителя каталогов.
  • Имя класса в конце Должно Совпадать с именем соответствующего файла с суффиксом. php.
  • Реализация автозагрузчика Не должна. Создать исключение, Не должно. Вывод информации об ошибке на любом уровне; и Не должно Есть возвращаемое значение.

3) пример

Стиль PSR-4

Имя класса: ZendAbc Префикс пространства имен: Zend Каталог базы файлов:/usr/include/Zend/Путь к файлу:/usr/include/Zend/Abc. PHP

Имя класса: Запрос ядра Symfony Префикс пространства имен: Базовый каталог файлов ядра Symfony:./поставщик/Symfony/Ядро/Путь к файлу:./поставщик/Symfony/Ядро/Запрос. PHP

структура каталогов

-vendor/
| -vendor_name/
| | -package_name/
| | | -src/
| | | | -ClassName.php       # Vendor_Name\Package_Name\ClassName
| | | -tests/
| | | | -ClassNameTest.php   # Vendor_Name\Package_Name\ClassNameTest

Что сделал композитор?

  • У вас есть проект, который зависит от нескольких библиотек.
  • Некоторые из этих библиотек зависят от других библиотек.
  • Вы заявляете, от чего вы зависите.
  • Composer выяснит, какие версии пакетов необходимо установить, и установит их (загрузите их в свой проект).

Например, вы создаете проект, который требует некоторого модульного тестирования. Вы решаете использовать его phpunit . Чтобы добавить его в свой проект, все, что вам нужно сделать, это composer. json Зависимости проекта описаны в файле.

 {
   "require": {
     "phpunit/phpunit":"~6.0",
   }
 }

Затем в composer требуется После этого нам просто нужно сразу перейти к проекту. используйте Класс phpunit готов к использованию.

Что происходит, когда выполняется требование композитора

  • Composer найдет источник сторонних библиотек, соответствующих спецификации PR4
  • Загрузите его в каталог поставщиков
  • Инициализируйте сопоставление доменного имени верхнего уровня и запишите его в указанный файл

(например: 'PHPUnit\\Framework\\Assert' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Assert.php' )

  • Напишите функцию автоматической загрузки и зарегистрируйте ее в spl_autoload_register()

Тема не по теме: Теперь многие фреймворки помогли нам написать сопоставление доменных имен верхнего уровня. Нам просто нужно создать новые файлы в фреймворке, записать пространство имен в новые файлы и использовать наше пространство имен в любом месте.

Теперь давайте посмотрим, как реализован composer, проанализировав исходный код Стандарт PSR 4 Функция автоматической загрузки.

Многие фреймворки внедряют composer для автоматической загрузки при инициализации. Возьмем в качестве примера Laravel, первое предложение его индекса входного файла. PHP должен использовать composer для достижения автоматической загрузки.

запуск

В каталог поставщиков autoload.php :

Вот где Композитор действительно начал.

Композитор автоматически загружает файлы

Во-первых, давайте получим общее представление об исходных файлах, которые Composer использует для автоматической загрузки.

  1. Autoload_real.php: Загрузочный класс для функции автоматической загрузки.

    • Инициализация загрузочного класса composer (Инициализация пространств имен верхнего уровня и сопоставление путей к файлам) И регистрация (spl_autoload_register()).
  2. ClassLoader.php: Композитор загружает класс.

    • Основной класс функции автоматической загрузки композитора.
  3. Autoload_static.php: Класс инициализации пространства имен верхнего уровня,

    • Используется для инициализации пространства имен верхнего уровня для основного класса.
  4. Autoload_classmap.php: Простейшая форма автоматической загрузки,

    • Он имеет полное отображение пространства имен и каталога файлов.
  5. Autoload_files.php: Файл, используемый для загрузки глобальной функции.

    • Сохраните имена путей к файлам, в которых расположены глобальные функции.
  6. Autoload_namespaces.php: Файл автоматической загрузки, соответствующий стандарту PSR 0.

    • Сохраняется сопоставление между пространством имен верхнего уровня и файлом.
  7. Autoload_psr4.php: Файл автоматической загрузки, соответствующий стандарту PSR 4.

    • Сохраняется сопоставление между пространством имен верхнего уровня и файлом.

Классическая загрузка Autoload_real

В каталоге поставщиков autoload.php Как вы можете видеть из файла, программа в основном вызывает статические методы загрузочных классов. getLoader() Итак, давайте продолжим рассмотрение этой функции.

= 50600 && !defined('HHVM_VERSION');

      if ($useStaticLoader) {
          require_once __DIR__ . '/autoload_static.php';

          call_user_func(
          \Composer\Autoload\ComposerStaticInit7b790917ce8899df9af8ed53631a1c29::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);
          }
      }

      / ************************************* Registration automatically loads core class objects*********************************/
      $loader->register(true);

      / *********************************** Autoloading Global Function***********************************************/
      if ($useStaticLoader) {
          $includeFiles = Composer\Autoload\ComposerStaticInit7b790917ce8899df9af8ed53631a1c29::$files;
      } else {
          $includeFiles = require __DIR__ . '/autoload_files.php';
      }

      foreach ($includeFiles as $fileIdentifier => $file) {
          composerRequire7b790917ce8899df9af8ed53631a1c29($fileIdentifier, $file);
      }

      return $loader;
    }

Я разделяю класс автоматической загрузки на пять частей.

Часть I – Одиночки

Первая часть очень проста. Это самый классический одноэлементный режим. Может быть только один класс автоматической загрузки.

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

= 50600 && !defined('HHVM_VERSION');
  if ($useStaticLoader) {
     require_once __DIR__ . '/autoload_static.php';

     call_user_func(
       \Composer\Autoload\ComposerStaticInit7b790917ce8899df9af8ed53631a1c29::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);
      }
    }

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

1. Autoload_static is used for static initialization.
  2. Initialize the core class interface.

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

prefixLengthsPsr4
                          = ComposerStaticInit7b790917ce8899df9af8ed53631a1c29::$prefixLengthsPsr4;

          $loader->prefixDirsPsr4
                          = ComposerStaticInit7b790917ce8899df9af8ed53631a1c29::$prefixDirsPsr4;

          $loader->prefixesPsr0
                          = ComposerStaticInit7b790917ce8899df9af8ed53631a1c29::$prefixesPsr0;

          $loader->classMap
                          = ComposerStaticInit7b790917ce8899df9af8ed53631a1c29::$classMap;

      }, null, ClassLoader::class);
  }

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

 __DIR__ . '/../..' . '/app/Console/Kernel.php',

      'App\Exceptions\Handler'
              => __DIR__ . '/../..' . '/app/Exceptions/Handler.php',

      '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__ . '/../..' . '/app/Http/Controllers/Auth/RegisterController.php',
  ...)

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

 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',
    ),
  ...)

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

 26,

Часть 2. Построение основных классов загрузчика классов

 array (
              0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
          )

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

 $path) {
       $loader->set($namespace, $path);
    }

    // PSR4 standard
    $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);
    }

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

 array($vendorDir . '/dnoegel/php-xdg-base-dir/src'),

    'Webmozart\Assert\'
        => array($vendorDir . '/webmozart/assert/src'),

    'TijsVerkoyen\CssToInlineStyles\'
        => array($vendorDir . '/tijsverkoyen/css-to-inline-styles/src'),

    'Tests\'
        => array($baseDir . '/tests'),

    'Symfony\Polyfill\Mbstring\'
        => array($vendorDir . '/symfony/polyfill-mbstring'),
    ...
    )

Часть 2. Построение основных классов загрузчика классов

fallbackDirsPsr4 = (array) $paths;
        } else {
            $length = strlen($prefix);
            if ('\' !== $prefix[$length - 1]) {
                throw new \InvalidArgumentException(
                  "A non-empty PSR-4 prefix must end with a namespace separator."
                );
            }
            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
            $this->prefixDirsPsr4[$prefix] = (array) $paths;
        }
    }

Часть 2. Построение основных классов загрузчика классов

(prefix - > top-level namespace, top-level namespace - > top-level namespace length)
(Top namespace - > directory)

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

 __DIR__ . '/../..' . '/app/Console/Kernel.php',

    'App\Exceptions\Handler'
        => __DIR__ . '/../..' . '/app/Exceptions/Handler.php',
    ...
)

Часть 2. Построение основных классов загрузчика классов

classMap) {
            $this->classMap = array_merge($this->classMap, $classMap);
        } else {
            $this->classMap = $classMap;
        }
    }

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

public static function getLoader()
 {
    / *********************************************** Classic Single Case Model **********************************************************/
    if (null !== self::$loader) {
        return self::$loader;
    }
    
    / ************************************* Get automatic loading of core class objects*******************************/
    spl_autoload_register(array('ComposerAutoloaderInit
    7b790917ce8899df9af8ed53631a1c29', 'loadClassLoader'), true, true);
    
    self::$loader = $loader = new \Composer\Autoload\ClassLoader();
    
    spl_autoload_unregister(array('ComposerAutoloaderInit
    7b790917ce8899df9af8ed53631a1c29', 'loadClassLoader'));

    / ********************************* Initialization of Autoloading Core Class Objects*********************************/
    $useStaticLoader = PHP_VERSION_ID >= 50600 && 
    !defined('HHVM_VERSION');
    
    if ($useStaticLoader) {
        require_once __DIR__ . '/autoload_static.php';

        call_user_func(\Composer\Autoload\ComposerStaticInit
        7b790917ce8899df9af8ed53631a1c29::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);
        }
    }

    / ************************************* Registration automatically loads core class objects*********************************/
    $loader->register(true);

    / *********************************** Autoloading Global Function***********************************************/
    if ($useStaticLoader) {
        $includeFiles = Composer\Autoload\ComposerStaticInit
        7b790917ce8899df9af8ed53631a1c29::$files;
    } else {
        $includeFiles = require __DIR__ . '/autoload_files.php';
    }
    
    foreach ($includeFiles as $fileIdentifier => $file) {
        composerRequire
        7b790917ce8899df9af8ed53631a1c29($fileIdentifier, $file);
    }

    return $loader;
}

Часть 2. Построение основных классов загрузчика классов

public function register($prepend = false)
{
    spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}

Часть 2. Построение основных классов загрузчика классов

public function loadClass($class)
    {
        if ($file = $this->findFile($class)) {
            includeFile($file);

            return true;
        }
    }

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

if ($useStaticLoader) {
    $includeFiles = Composer\Autoload\ComposerStaticInit7b790917ce8899df9af8ed53631a1c29::$files;
} else {
    $includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
    composerRequire7b790917ce8899df9af8ed53631a1c29($fileIdentifier, $file);
}

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

public static $files = array (
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
...
);

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
    
return array(
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
   ....
);

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

class ComposerAutoloaderInit7b790917ce8899df9af8ed53631a1c29{
  public static function getLoader(){
      ...
      foreach ($includeFiles as $fileIdentifier => $file) {
        composerRequire7b790917ce8899df9af8ed53631a1c29($fileIdentifier, $file);
      }
      ...
  }
}

function composerRequire7b790917ce8899df9af8ed53631a1c29($fileIdentifier, $file)
 {
    if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
        require $file;

        $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
    }
}

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

public function loadClass($class)
{
    if ($file = $this->findFile($class)) {
        includeFile($file);

        return true;
    }
}

public function findFile($class)
{
    // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
    if ('\' == $class[0]) {
        $class = substr($class, 1);
    }

    // class map lookup
    if (isset($this->classMap[$class])) {
        return $this->classMap[$class];
    }
    if ($this->classMapAuthoritative) {
        return false;
    }

    $file = $this->findFileWithExtension($class, '.php');

    // Search for Hack files if we are running on HHVM
    if ($file === null && defined('HHVM_VERSION')) {
        $file = $this->findFileWithExtension($class, '.hh');
    }

    if ($file === null) {
        // Remember that this class does not exist.
        return $this->classMap[$class] = false;
    }

    return $file;
}

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

private function findFileWithExtension($class, $ext)
{
    // PSR-4 lookup
    $logicalPathPsr4 = strtr($class, '\', DIRECTORY_SEPARATOR) . $ext;
    
    $first = $class[0];
    if (isset($this->prefixLengthsPsr4[$first])) {
        foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
            if (0 === strpos($class, $prefix)) {
                foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
                    if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
                        return $file;
                    }
                }
            }
        }
    }

    // PSR-4 fallback dirs
    foreach ($this->fallbackDirsPsr4 as $dir) {
        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
            return $file;
        }
    }
    
    // PSR-0 lookup
    if (false !== $pos = strrpos($class, '\')) {
        // namespaced class name
        $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
            . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
    } else {
        // PEAR-like class name
        $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
    }
    
    if (isset($this->prefixesPsr0[$first])) {
        foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
            if (0 === strpos($class, $prefix)) {
                foreach ($dirs as $dir) {
                    if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
                        return $file;
                    }
                }
            }
        }
    }
    
    // PSR-0 fallback dirs
    foreach ($this->fallbackDirsPsr0 as $dir) {
        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
            return $file;
        }
    }
    
    // PSR-0 include paths.
    if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
        return $file;
    }
}

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

  • Часть 2. Построение основных классов загрузчика классов
  • Часть 2. Построение основных классов загрузчика классов
        p' => 
            array (
                'phpDocumentor\Reflection\' => 25,
                'phpDocumentor\Fake\' => 19,
          )
  • Часть 2. Построение основных классов загрузчика классов
  • Часть 2. Построение основных классов загрузчика классов
  • Часть 2. Построение основных классов загрузчика классов
    'phpDocumentor\Reflection\' => 
        array (
            0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src',
            1 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src',
            2 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src',
        ),
  • Часть 2. Построение основных классов загрузчика классов
  • Часть 2. Построение основных классов загрузчика классов Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов

Часть 2. Построение основных классов загрузчика классов