При попытке выполнить некоторую обработку ошибок, когда моя функция __autoload () не загружает файл, я наткнулся на эту маленькую «странность».
Согласно http://nl.php.net/autoload Исключения из функции __autoload () могут быть обнаружены в блоке catch с PHP версии 5.3+.
Примечание. До 5.3.0 исключения, брошенные в функцию __autoload, не могли быть пойманы в блоке catch и привели бы к фатальной ошибке. Из исключений 5.3.0+, брошенных в функцию __autoload, можно попасть в блок catch с 1 условием. Если вы выбрали специальное исключение, тогда должен быть доступен настраиваемый класс исключений. Функция __autoload может использоваться рекурсивно для автозагрузки настраиваемого класса исключений.
Это отлично работает для типа обработки ошибок, который я имел в виду. Приведенный ниже пример работает так же, как я хочу (он выдает исключение и его поймал):
function __autoload($class) { throw new Exception(); } try { new UndefinedClass(); } catch (Exception $e) { echo 'damnit, it no work!'; }
Выход: черт возьми, это не работа!
Если, однако, я пробую одну и ту же концепцию со статическим вызовом метода из неопределенного класса, Исключения не выбрасываются, вместо этого я получаю фатальную ошибку.
try { $a = UndefinedClass::someRandomStaticMethod(); } catch (Exception $e) { echo 'meh, it no work!'; }
Вывод: фатальная ошибка: класс «UndefinedClass» не найден в * ** * * в строке 16
Приведенный выше код не работает. Исключение не выбрасывается. (используется такая же функция __autoload ()).
http://nl.php.net/autoload ничего не упоминает об этой утилите, и это оставляет мне интересно, не делаю ли я что-то ужасное здесь? Как я могу заставить свою функцию __autoload () исключать исключения при вызове статических методов несуществующего класса?
Если это невозможно с помощью функции __autoload (), разрешает ли spl_autoload () этот тип исключения?
@Galled
Основываясь на ссылке, которую вы предоставили, я заменил функцию __autoload () следующим образом:
function __autoload($class) { eval(' class ' . $class . ' { }; '); throw new Exception('Im an Exception!'); }
С помощью этой версии фатальная ошибка больше не подается на мой монитор. Однако теперь он будет кормить меня другой фатальной ошибкой: тот факт, что someRandomStaticMethod () не существует.
Я мог бы, конечно, включить объявление метода в вызов eval (). Но это не выполнимое решение, так как я должен был бы переопределить каждый класс, который мой проект содержит в функции __autoload (), чтобы избежать этой фатальной ошибки. Также интересно знать, что исключение отсутствует, так как кажется, что фатальная ошибка возникает до того, как обрабатывается исключение, если оно даже выбрано в первую очередь.
Мне несколько удалось решить проблему, расширив предложения от Galled. После некоторого большего чтения, особенно здесь: http://nl.php.net/manual/en/function.spl-autoload-register.php#84086 Я написал следующее.
function __autoload($class) { ... /* if something and/or everything fails */ eval(' class ' . $class . ' { public function __construct() { throw new Exception(\'Im an Exception!\'); } public static function __callstatic($method, $arguments) { throw new Exception(\'Im an Exception!\'); } }; '); }
Этот вариант теперь будет генерировать Exceptions
на обоих вариантах использования. независимо от наличия методов внутри класса.
Хотя вышеизложенное работает, я надеюсь, что кто-то может предоставить решение, которое не касается функции eval()
. Поскольку, по какой-то причине, я чувствую, что я просто приставал к PHP.