Вроде бы простой код: PHP: set_exception_handler(function (Throwable $t) { echo $t->getMessage; }); require_once 'not-exists.php'; Вылазит ошибка, а должно быть исключение: Fatal error: main(): Failed opening required 'not-exists.php' (include_path='.;e:/ospanel/modules/php/PHP-7.1;e:/ospanel/modules/php/PHP-7.1/PEAR/pear') in ..............\test.php on line 10
Fatal error: main(): Failed opening required 'not-exists.php' (include_path='.;e:/ospanel/modules/php/PHP-7.1;e:/ospanel/modules/php/PHP-7.1/PEAR/pear') in ..............\test.php on line 10 Но я ждал исключение. Возможно я чего-то недопонимаю https://www.php.net/manual/ru/language.errors.php7.php
Почему? Потому что так устроен PHP. Механизм exception вообще в пыхе как-то сбоку прилеплен. Ещё лет 12 назад Котеров исследовал как перехватывать максимум ошибок. Погугли "Котеров fatal error" Update: http://dklab.ru/chicken/nablas/45.html https://www.php.net/manual/ru/function.set-error-handler#88401
Там нечего перехватывать. Задает обработчик по умолчанию для случаев, когда исключение выброшено вне блока try/catch. После вызова exception_handler выполнение будет остановлено. https://www.php.net/manual/ru/function.set-exception-handler.php
@qdevelopment нечего в смысле ты не перехватишь через try-catch подобную ошибку: Fatal error: main(): Failed opening required 'not-exists.php' предлагаю попробовать. --- Добавлено --- PHP: <?php function exception_handler(\Throwable $exception) { echo "Error intercepted!\n"; } set_exception_handler('exception_handler'); try { require 'nonexistent.php'; } catch (\Throwable $e) { echo "Got it!\n"; } не будет сообщения "Got it!" или "Error intercepted!" некоторые ошибки более шустрые чем другие.
@artoodetoo чтобы set_exception_handler подхватил исключение, сперва это исключение должно быть выброшено. То что файла not-exists.php нет, не выбрасывает исключение, а получает fatal error. Т.е ему надо с помощью set_error_handler сперва подхватить ошибку и там выбросить throw new Exception, чтобы заработал set_exception_handler Или же писать что-то типа PHP: set_exception_handler(function (Throwable $t) { echo $t->getMessage(); }); if (!file_exists('not-exists.php')) { throw new Exception('No such file'); }
@qdevelopment спасибо, хорошее замечание про error handler. Исторически сложилось, что в PHP есть старый вид ошибок и исключения. Они как бы параллельно существуют. Хотя в свежих версиях языка их пытаются привести к общему знаменателю через интерфейс Throwable. Конечно, в данном случае можно соломки постелить и проверять наличие файла через if. Или заменить require на include и так добиться снижения уровня ошибки до Warning. Ибо Fatal error неизбежно прерывает выполнение скрипта, даже с set_error_handler().
@artoodetoo Да точно, совсем забыл, что в require ошибка уровня E_COMPILE_ERROR, поэтому set_error_handler не поможет. Идея с заменой require на include, думаю самая оптимальная.
сделал тестовый полигон. не знаю насколько он будет понятен топикстартеру, но вот: описаны 4 случая разных ошибок, можно раскомментировать одну из них и закомментировать остальные и смотреть что выведется в итоге. PHP: <?php error_reporting(0); function legacy_error_handler($errno, $errstr, $errfile, $errline) { # if (0 === error_reporting()) { # return false; # } echo "Error intercepted\n"; throw new \ErrorException($errstr, 0, $errno, $errfile, $errline); } set_error_handler('legacy_error_handler'); function exception_handler(\Throwable $exception) { echo "Exception intercepted without try-catch!\n"; } set_exception_handler('exception_handler'); try { // 1. "natural" fatal error require 'nonexistent.php'; // 2. warning # 1/0; // 3. user generated error/warning # trigger_error('OOPS!', E_USER_WARNING); // 4. raise exception # throw new \Exception('OMG OMG OMG'); } catch (\Throwable $e) { // For PHP 7 echo "Cought as Throwable\n"; } catch (\Exception $e) { // For PHP 5 // handle $e echo "Cought as Exception\n"; } echo "Continue\n"; --- Добавлено --- Если увидел строку "Continue", значит ошибка полностью под контролем.
Главное не сходить с ума, не впадать в крайности и исключения использовать для исключительных ситуаций. А наличие, чтение и запись файла надо проверять и обрабатывать соответствующим образом.