class_exists вызывает spl_autoload_register

Я создаю простой скрипт для классов автозагрузки, но когда я использую class_exists, выполняется spl_autoload_register, например:

<?php
function autoLoadClass($name) {
    echo 'spl_autoload_register: ', $name, '<br>';
}

spl_autoload_register('autoLoadClass');

class_exists('Foo');
class_exists('Bar');
class_exists('Foo\\Bar');

Выход:

spl_autoload_register: Foo
spl_autoload_register: Bar
spl_autoload_register: Foo\Bar

Это правильно? Есть ли способ заставить «spl_autoload» игнорировать вызовы «class_exists»?


person Guilherme Nascimento    schedule 16.10.2015    source источник
comment
У вас есть вопрос о class_exists, так почему бы вам не поискать его на странице руководства?!   -  person Rizier123    schedule 16.10.2015
comment
@Rizier123 Спасибо, что разочаровали.   -  person Guilherme Nascimento    schedule 16.10.2015
comment
Мой комментарий не должен обескураживать вас. Это должно быть чем-то вроде напоминания/информации, чтобы всегда проверять руководство, если у вас есть вопрос/проблема с определенной функцией.   -  person Rizier123    schedule 16.10.2015
comment
@ Rizier123 Так что плохие вопросы здесь с положительными голосами. Верно? Однако некоторые действия только отпугивают. Поверьте, я всегда читал руководство, только ему не хватало внимания, и я думаю, что вопрос все же скорее помог сформулировать хороший ответ, который помимо содержания руководства содержит альтернативный пример. Спасибо.   -  person Guilherme Nascimento    schedule 16.10.2015


Ответы (1)


Вы можете сделать так, чтобы class_exists не вызывал автозагрузку.
Из руководства:

bool class_exists ( string $class_name [, bool $autoload = true ] )

Итак, вызов типа:

class_exists('Foo', false);

будет игнорировать автозагрузку.

[ Демо ]

Также возможно заставить функцию автозагрузки игнорировать вызовы из class_exists с помощью (ab)использования debug_backtrace, но этот метод уродлив и очень медленный, но для полноты картины, вот как это сделать:

function autoLoadClass($name) {
    foreach(debug_backtrace() as $call) {
        if(!array_key_exists('type', $call) && $call['function'] == 'class_exists') {
            return;
        }
    }
    echo 'spl_autoload_register: ', $name, '<br>';
}

(Примечание: похоже, это не работает в HHVM)

Это в основном прерывает функцию, если одна из вызывающих функций вызывается class_exists, а $call['type'] не должно существовать, чтобы гарантировать, что такие вызовы, как SomeClass::class_exists и $someObject->class_exists, отфильтровываются.

[ Демо ]

person Siguza    schedule 16.10.2015
comment
Хороший пример с debug_backtrace :) Спасибо. Но class_exists(..., false); этого достаточно. Однако это хороший пример для изучения. Спасибо, что поощряете и даете хороший ответ, в отличие от других пользователей. - person Guilherme Nascimento; 16.10.2015