SPL Автозагрузка лучших практик

В моем include_path на стороне сервера у меня есть ссылка на каталог pear в каталоге / 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 бизнес или я делаю это несколько в правильном направлении?

2 ответа

Решение

Интересная вещь, которую делает автозагрузчик проекта 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

Другие вопросы по тегам