2012-04-28 3 views
1

Стараюсьspl_autoload_register против __autoload

function some_class($class) { 
     require PATH.'test'.$class.'.php'; 
    } 



function test_class($class) { 
     require PATH.'some'.$class.'.php'; 
    } 

    spl_autoload_register("test_class"); 
    spl_autoload_register("some_class"); 


    $tst = new SomeClass(); 

SomeClass класс найти в "PATH/некоторые/SomeClass.php", но spl_autoload_register вызов только функция "test_class" и не называют "some_class". Но если я меняю положение функций, то он найдет новый SomeClass.

ответ

4

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

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

При использовании нескольких функций автозагрузки рекомендуется использовать file_exists или include.

Вы также можете исключать исключения из своих функций автозагрузки, чтобы вы могли обрабатывать неопределенные классы грациозно, а не убивать скрипт, если класс не найден. За пример:

function my_autoload($class) { 
    $filename = "class.{$class}.php"; 

    if (!file_exists($filename)) 
     throw new Exception("$class not found"); 

    include_once $filename; 
} 

spl_autoload_register('my_autoload'); 

try { 
    $a = new Foo; 
} catch (Exception $e) { 
    // Foo wasn't found 
} 

// continuing the script... 

Очевидно, это зависит от ваших потребностей, как и бросать исключение остановит выполнение последующих функций автозагрузки.

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

+0

Почему не рекомендуется использовать автозагрузку? – Nick

+3

@Nick: 'spl_autoload_register' в порядке,' __autoload' не является, как [указано в руководстве] (http://php.net/__autoload). Он не обеспечивает большую гибкость и может быть устаревшим в будущем. – netcoder

+0

Спасибо .. Я добавлю file_exist и все работаю, но почему первая функция всегда терпит неудачу, если я использую «require»? Я использую «require», и ничего не получается. –

1

Лучше всего использовать одну функцию автозагрузки. Что-то вроде этого:

function some_class($class) { 
    if (file_exists(PATH.'test'.$class.'.php')) { 
     include PATH.'test'.$class.'.php'; 
    } elseif (file_exists(PATH.'some'.$class.'.php')) { 
     include PATH.'some'.$class.'.php'; 
    } else { 
     die('class '.$class.' not found'); 
    } 
} 
spl_autoload_register("some_class"); 
+0

Я знаю о 1 функции, мне просто нужно проверить 2 функции автозагрузки :) –

0

spl_autoload_register- Что именно это означает? Давайте попробуем понять это с помощью примера:

function Autoloader($className) 
    { 
     require_once $path.$className.'.php'; 
    } 

    spl_autoload_register('Autoloader'); 

    $myObj = new MyClass(); 

Здесь мы только экземпляр класса с именем, как «MyClass» с указанием отказа включить или требуют заявления.

Разве это не круто? Итак, как мы это сделали? Давайте заглянем.

Здесь мы зарегистрировали функцию под названием «Автозагрузчик» с функцией spl_autoload_register(). Когда мы создаем экземпляр «MyClass», имя класса (MyClass) передается PHP в «spl_autoload_register()», где зарегистрированная функция выбирает его как параметр. И при дешифровке функции Autoloader мы включили путь к этому файлу класса.

Это просто здорово! Подумайте о ситуации, когда у вас есть пара классов, и все они не будут использоваться в каждом случае ИЛИ на каждой странице. В таких случаях spl_autoload_register() может стать для вас настоящим спасителем.

Вам просто нужно создать экземпляр, а spl_autoload_register() позаботится об отдыхе.

Вместо регистрации функции вы также можете сделать это следующим образом:

spl_autoload_register(function ($class) { 
    include 'classes/' . $class . '.class.php'; 
}); 

Но этот кусок кода работает только с PHP> = 5.3.0

Вы можете рассмотреть spl_autoload_register() в виде замена __autoload(), который может быть определен как:

__autoload() - Попытка загрузить неопределенный класс

Давайте попробуем разобраться с помощь примера.

<?php 
// we've writen this code where we need 
function __autoload($classname) { 
    $filename = "./". $classname .".php"; 
    include_once($filename); 
} 

// we've called a class *** 
$obj = new myClass(); 
?> 

Но у вас есть недостаток в том, что вам нужно написать эту функцию в каждом из ваших файлов классов.

Смежные вопросы