Лучшие практики автозагрузки SPL

В моем include_path на стороне сервера у меня есть ссылка на каталог груши в «/usr/share/pear/». В свои приложения я включаю файлы из общей библиотеки, находящиеся в '/usr/share/pear/library/' с require_once 'library/file.php'.

Недавно я начал использовать автозагрузчик spl, я заметил, что в функции загрузчика вы должны определить логику, с помощью которой нужно включить файл. Мой первый способ сделать это - попытаться включить файл и подавить его с помощью @, чтобы посмотреть, не выйдет ли он из строя, например. @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 дело, или я делаю это в правильном направлении?


person meder omuraliev    schedule 11.11.2009    source источник


Ответы (2)


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

По сути, вы объявляете static внутри вашего __autoload(), который содержит массив всех файлов классов, проиндексированных классом, который вызовет их загрузку. Например, код будет использовать Dir или glob() для создания этого статического массива:

$class_files = array(
  'user' => '/var/www/htdocs/system/classes/user.class.php',
);

Затем вы просто включаете $class_files[$class], чтобы получить правильный файл. Это приятно и быстро, потому что он получает каталог с диска сразу, а не генерирует список или ищет определенное имя файла каждый раз, когда ссылаются на новый класс. (Вы будете удивлены, какая разница в скорости.)

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

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

person ringmaster    schedule 11.11.2009

Я лично иду путем использования

function autoload($class) {
    /* transform class name into filename ... */
    include $class;
}

даже без @ для облегчения отладки (ошибки закрываются/записываются в продакшн)

Вас также может заинтересовать соответствующее обсуждение в списке разработчиков PHP: http://marc.info/?t=125787162200003&r=1&w=2

person johannes    schedule 11.11.2009
comment
Разве автозагрузка spl не является более практичным и современным методом? Или они в принципе одинаковые? - person meder omuraliev; 06.12.2009