Как управлять автозагрузкой зависимостей - PullRequest
4 голосов
/ 09 сентября 2011

При создании библиотеки я всегда предоставляю класс 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. Хотя это тоже не кажется правильным.

Ответы [ 3 ]

8 голосов
/ 09 сентября 2011

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

  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. Производительность (по той же причине, что и 2-е решение)
      3. Большинство библиотек 3pd не поддерживают загрузочный файл, поэтому вам, возможно, придется его поддерживать.

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

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

2 голосов
/ 09 сентября 2011

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

0 голосов
/ 09 сентября 2011

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

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

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

$obj = new PHPParser_Autoloader();
...