Рекомендации по автозагрузке SPL
-
19-09-2019 - |
Вопрос
В моем include_path на стороне сервера у меня есть ссылка на каталог pear в '/usr/share/pear/'.В мои приложения я включаю файлы из общей библиотеки, находящиеся в '/usr/ share /pear/library/' с require_once 'library/file.php'
.
Недавно я начал использовать автозагрузчик spl, я заметил, что в функции loader вы должны определить логику, с помощью которой включать файл.Моим первым способом сделать это была попытка включить файл и подавить его с помощью @
чтобы увидеть, не выйдет ли из строя, например @include 'library/file.php'
однако я думаю, главным образом потому, что я много читаю о @
будучи плохой практикой, я решил вручную выполнить эту работу сам, взорвавшись get_include_path
по PATH_SEPARATOR
и посмотреть, соответствует ли каталог тому, каким я хочу его видеть, затем выполнить file_exists
и в том числе это.
Вот так:
function classLoader( $class ) {
$paths = explode( PATH_SEPARATOR, get_include_path() );
$file = SITE_PATH . 'classes' . DS . $class . '.Class.php';
if ( file_exists( $file) == false )
{
$exists = false;
foreach ( $paths as $path )
{
$tmp = $path . DS . 'library' . DS . 'classes' . DS . $class . '.Class.php';
if ( file_exists ( $tmp ) )
{
$exists = true;
$file = $tmp;
}
}
if ( !$exists ) { return false; }
}
include $file;
}
spl_autoload_register('classLoader');
Неужели я пошел не тем путем?Должен ли я был просто сделать @include
бизнес или я делаю это в какой-то степени в правильном направлении?
Решение
Одна вещь, которую Автозагрузчик проекта Habari что интересно, так это кэшировать весь список файлов класса в памяти, чтобы он не выполнял поиск файлов на диске каждый раз, когда запрашивается класс.
По сути, вы объявляете статическое значение внутри вашего __autoload()
который содержит массив всех файлов класса, проиндексированных классом, который вызовет их загрузку.Например, код будет использовать Dir или glob()
чтобы сгенерировать этот статический массив:
$class_files = array(
'user' => '/var/www/htdocs/system/classes/user.class.php',
);
Затем вы просто включаете $class_files[$class]
чтобы получить правильный файл.Это удобно и быстро, потому что он получает каталог с диска сразу, вместо того чтобы генерировать список или искать конкретное имя файла каждый раз, когда ссылаются на новый класс.(Вы были бы удивлены, насколько велика разница в скорости, которую это имеет.)
Если имя класса не является ключом в массиве, вы можете создать пользовательское исключение или сгенерировать заглушку / макет класса для возврата.Кроме того, если вы заглянете в автозагрузчик системы Habari, вы увидите, что Habari реализует __static()
в классах, которые загружаются автоматически, что похоже на конструктор для статических классов.
include_once()
следует избегать, и @
оператор не нужен, если вы проверили наличие файла для включения.
Другие советы
Я лично иду по этому пути, используя
function autoload($class) {
/* transform class name into filename ... */
include $class;
}
даже без @ для облегчения отладки (ошибки завершаются / регистрируются в рабочей среде)
Вас также может заинтересовать соответствующее обсуждение в списке разработчиков PHP: http://marc.info/?t=125787162200003&r=1&w=2