SPL Автозагрузка лучших практик - PullRequest
5 голосов
/ 11 ноября 2009

В моем 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 ]

6 голосов
/ 11 ноября 2009

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

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

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

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

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

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

1 голос
/ 11 ноября 2009

Я лично иду путем

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

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

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

...