Intereting Posts

Как управлять автозагрузкой зависимостей

При создании библиотеки я всегда предоставляю класс Autoloader который обрабатывает автозагрузку для библиотеки. Автозагрузчик зарегистрирован следующим образом:

 require_once 'path/to/PHP-Parser/lib/PHPParser/Autoloader.php'; PHPParser_Autoloader::register(); 

Я не уверен, как справиться с этим, если моя библиотека зависит от другой библиотеки. Представьте, что PHPParser зависит от PHPLexer . Теперь при использовании библиотеки нужно будет написать:

 require_once 'path/to/PHP-Lexer/lib/PHPLexer/Autoloader.php'; PHPLexer_Autoloader::register(); require_once 'path/to/PHP-Parser/lib/PHPParser/Autoloader.php'; PHPParser_Autoloader::register(); 

Если есть более чем одна зависимость или зависимости зависят от самих зависимостей, это может стать беспорядочным.

Итак, как следует обрабатывать автозагрузку зависимостей ?

Одна из моих идей заключалась в том, что библиотека также должна обрабатывать автозагрузку для своих зависимостей, но это просто не так. Другая идея заключалась бы в том, чтобы не предоставлять автозагрузчик вообще и предположить, что люди используют UniversalClassLoader . Это, хотя и не кажется правильным.

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

  1. Используйте общий автозагрузчик PSR-0 для всех библиотек и просто зарегистрируйте местоположение другого проекта при его инициализации.

    • Преимущества:
      1. Очень просто реализовать
      2. Использует один и тот же код, поэтому можно использовать только один автозагрузчик
      3. Вы можете зарегистрировать все пути в файле загрузочного файла приложения, поэтому вся автозагрузка библиотек определена в одном месте
    • Недостатки
      1. Требует, чтобы все библиотеки реализовали файловую структуру, совместимую с PSR-0
      2. Ускоряет уровень абстракции, так как загрузочная загрузка приложения должна загружать все внутри приложения, включая каждую отдельную библиотеку.
      3. Плотно связывает файловую структуру библиотеки с вашим автозагрузчиком (если библиотека реализует новый файл, который конфликтует, он сломает ваш автозагрузчик, даже если их файл работает)
  2. Определите пользовательский автозагрузчик для каждой библиотеки.

    • преимущества
      1. Очень просто реализовать.
      2. Сохраняет библиотеку автоматической загрузки семантики в библиотеке.
      3. Улучшенный код поддержки из-за разделения ответственности
    • Недостатки
      1. В вашем загрузочном файле много жестко закодированных классов (неважное дело)
      2. Производительность, поскольку класс автозагрузки должен проходить через несколько автозагрузчиков
      3. Удерживает уровень абстракции, поскольку библиотеке может потребоваться больше усилий для загрузки, чем просто автозагрузка
  3. Внедрите bootstrap.php для каждой библиотеки (желательно предоставленной библиотекой)

    • преимущества
      1. Довольно просто реализовать.
      2. Сохраняет библиотеку автозагрузки семантики в библиотеке
      3. Лучший код из-за разделения проблем
      4. Возможность определения нетривиального кода начальной загрузки библиотеки без помутнения других частей приложения
    • Недостатки
      1. Все еще требуется require_once '/path/to/lib/dir/bootstrap.php'; инициализировать
      2. Производительность (по той же причине, что и второе решение)
      3. Большинство библиотек 3pd не реализуют файл начальной загрузки, поэтому вам, возможно, придется его поддерживать.

Лично я использую третий вариант. Примером является файл bootstrap.php в моей библиотеке CryptLib. Чтобы инициализировать его, просто вызовите bootstrap. Вы также можете использовать любой автозагрузчик PSR-0 и просто не вызывать bootstrap.php, и он будет работать нормально. Но с опцией bootstrap, если бы я добавил функциональные возможности, необходимые для регистрации при запуске, я мог бы просто добавить его в файл bootstrap.php, и он будет автоматически выполнен (вместо того, чтобы сообщать пользователям, что им нужно будет делать «x, y , z "при запуске) …

Что касается опции универсального загрузчика классов, которую вы упомянули (вызов spl_autoload_register() без аргументов), мне лично это не нравится. Прежде всего, это уменьшает имя класса (что является нарушением PSR-0, и мне это не нравится. Я привык к сопоставлению пути к классу case>> и на самом деле предпочитаю его таким образом). Во-вторых, он всегда использует относительные пути, поэтому он побеждает большинство кэшей операций. Есть и другие проблемы, но это большие …

Если классы в библиотеке называются соглашением PSR-0, то можно использовать один автозагрузчик для всех библиотек. В противном случае библиотека должна предоставить собственный автозагрузчик.

добавить в конструктор класса

 public function __construct(){ $this->Register(); } 

после этого на странице, где вы хотите сделать загрузку, создайте объект

 $obj = new PHPParser_Autoloader();