Импорт пакета или автозагрузка для PHP?

Какое решение вы бы порекомендовали для включения файлов в проект PHP?

  1. Нет ручных вызовов функций require/include — все загружается через функции автозагрузки
  2. Импорт пакетов, когда это необходимо.

Вот API импорта пакетов:

import('util.html.HTMLParser');
import('template.arras.*'); 

В этом объявлении функции вы можете разделить строку точками (разделитель иерархии пакетов), перебирая файлы в конкретном пакете (папке), чтобы включить только один из них или все из них, если в конце строки находится символ звездочки, например ('template.arras.*').

Одно из преимуществ, которые я вижу в методе импорта пакетов, заключается в том, что он может заставить вас использовать лучшую декомпозицию объектов и группировку классов.

Один из недостатков, который я вижу в методе автозагрузки, заключается в том, что функция автозагрузки может стать очень большой и не очень очевидной/читабельной.

Что вы думаете об этом?

  • Какие преимущества/недостатки вы можете назвать в каждом из этих методов?
  • Как найти лучшее решение для проекта?
  • Как узнать, возникнут ли проблемы с производительностью при использовании управления пакетами?

person Nikita Fedyashev    schedule 05.03.2009    source источник
comment
еще один вопрос по этой теме: stackoverflow .com/questions/791899/   -  person grossvogel    schedule 31.05.2010


Ответы (6)


Я широко использую __autoload(). Функция автозагрузки, которую мы используем в нашем приложении, имеет несколько настроек для обратной совместимости со старыми классами, но обычно мы следуем соглашению при создании новых классов, которые позволяют автозагрузке() работать довольно незаметно:

  • Последовательное именование классов: каждый класс в своем собственном файле, каждый класс именуется в верблюжьем регистре, разделенном символом подчеркивания. Это соответствует пути к классу. Например, Some_CoolClass сопоставляется с каталогом нашего класса, а затем с «Some/CoolClass.class.php». Я думаю, что некоторые фреймворки используют это соглашение.
  • Явно запрашивать внешние классы: поскольку мы не можем контролировать имена каких-либо внешних библиотек, которые мы используем, мы загружаем их с помощью PHP-функции require_once().
person jonstjohn    schedule 05.03.2009

Метод импорта является улучшением, но по-прежнему загружает больше, чем нужно.
Либо с помощью звездочки, либо загружая их в начале скрипта (поскольку импорт перед каждым новым именем класса станет громоздким).

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

Недостатком является то, что для правильной работы с каталогами требуется дополнительная логика.

person Bob Fanger    schedule 05.03.2009

Я использую require_once("../path-to-auto-load-script.php.inc") с автоматической загрузкой

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

например, все классы имеют определенное расширение, такое как inc.php
(поэтому я знаю, что они будут в каталоге /cls)
и
все файлы inc начинаются с .ht (поэтому они будут в каталоге /inc)

автозагрузка принимает один параметр: className, который я затем использую, чтобы определить, где на самом деле находится файл. зацикливание, как только я узнаю, какой у меня целевой каталог, каждый раз добавляя «../» для учета подстраниц (что, казалось, прерывало автоматическую загрузку для меня) и, наконец, require_once'ing фактического файла кода после его обнаружения.

person m42    schedule 05.03.2009

Вместо этого я настоятельно рекомендую сделать следующее:

Бросьте все свои классы в статический массив, className => filepath/classFile. Функция автоматической загрузки может использовать это для загрузки классов.

Это гарантирует, что вы всегда загружаете минимальное количество файлов. Это также означает, что вы избегаете совершенно глупых имен классов и разбора названных имен.

Если он медленный, вы можете добавить какой-нибудь ускоритель, и это принесет вам гораздо больше, если он все еще медленный, вы можете запустить процесс «компиляции», где часто используемые файлы просто сбрасываются в общие файлы, и ссылки автозагрузки могут быть обновлены, чтобы указывать на правильное место.

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

person Saem    schedule 05.03.2009

Я не фанат __autoload(). Во многих библиотеках (например, в некоторых библиотеках PEAR) разработчики используют class_exists() без передачи относительно нового второго параметра. Любой устаревший код, который у вас есть, также может иметь эту проблему. Это может вызвать предупреждения и ошибки, если вы определили __autoload().

Однако, если ваши библиотеки чисты и у вас нет устаревшего кода, с которым нужно работать, это фантастический инструмент. Иногда мне хочется, чтобы PHP был немного умнее в том, как они управляли поведением class_exists(), потому что я думаю, что проблема в этой функциональности, а не в __autoload().

person Jeremy DeGroot    schedule 05.03.2009

Создание собственной упаковочной системы, вероятно, является плохой идеей. Я бы посоветовал вам использовать явное ручное включение или автозагрузку (или их комбинацию, если на то пошло).

person troelskn    schedule 05.03.2009