#10.8 php Преобразование ошибок в исключения. Библиотека PHP_Exceptionizer. Иерархия уровней ошибок. Фильтрация по типам ошибок
Primary tabs
Вспомним, что нефатальные ошибки типа E_WARNING
, E_NOTICE
и т.д., не нарушают нормальный ход работы программы, и возникновение их в программе приводит, максимум, к уведомлению в окне браузера или записи в лог-файл (если отслеживание соответствующего типа ошибки включено в конфигурационном файле php.ini).
Однако на практике появление даже такой "несерьёзной" с точки зрения PHP ошибки в программе может свидетельствовать о серьёзном нарушении хода программы с точки зрения её логики, которое, возможно, делает весь дальнейший код просто бессмысленным.
Пример: открытие несуществующего файла приводит к ошибке уровня E_WARNING
(нефатальная ошибка). Однако если данный файл по логике программы содержит некоторый код, который необходимо выполнить в рамках текущего скрипта, то, очевидно, что одного только уведомления о невозможности открыть файл для нормальной работы алгоритма здесь недостаточно.
Как говорилось в предыдущих разделах, нефатальные ошибки могут быть перехвачены и обработаны пользовательским обработчиком, который устанавливается с помощью функции set_error_handler()
.
Другой подход заключается в автоматическом преобзовании перехватываемых ошибок в объекты исключений одноименных классов (E_WARNING
, E_NOTICE
и т.д.), и этот способ имеет следующие преимущества:
- Объект-исключение содержит информацию о месте возникновения ошибки, а также стек вызовов функций, которые можно извлечь с помощью соответствующих методов класса
Exception
- Есть возможность по-разному обрабатывать различные типы ошибок (исключений):
<?php try { //проверяемый код } catch (E_WARNING $e) { //код обработчика E_WARNING } catch (E_NOTICE $e) { //код обработчика E_NOTICE }
- Можно преобразовывать в исключения не все типы ошибок, а только некоторые из них (например, только
E_WARNING
) - Классы-исключения объединены в иерархию наследования: при необходимости можно отлавливать ошибки не только того типа, который указан у параметра блока
catch
, но и наследуемые (более серьезные) типы ошибок
Код библиотеки PHP_Exceptionizer
<?php class PHP_Exceptionizer { public function __construct($mask = E_ALL, $ignoreOther = false) { $catcher = new PHP_Exceptionizer_Catcher(); $catcher->mask = $mask; $catcher->ignoreOther = $ignoreOther; $catcher->prevHdl = set_error_handler(array($catcher, "handler")); } public function __destruct() { restore_error_handler(); } } class PHP_Exceptionizer_Catcher { public $mask = E_ALL; public $ignoreOther = false; public $prevHdl = null; public function handler($errno, $errstr, $errfile, $errline) { if (!($errno & error_reporting())) return false; if (!($errno & $this->mask)) { if (!$this->ignoreOther) { if ($this->prevHdl) { $args = func_get_args(); call_user_func_array($this->prevHdl, $args); } else { return false; } } return true; } $types = array( "E_ERROR", "E_WARNING", "E_PARSE", "E_NOTICE", "E_CORE_ERROR", "E_CORE_WARNING", "E_COMPILE_ERROR", "E_COMPILE_WARNING", "E_USER_ERROR", "E_USER_WARNING", "E_USER_NOTICE", "E_STRICT", "E_RECOVERABLE_ERROR", "E_DEPRECATED", "E_USER_DEPRECATED", ); $className = "E_EXCEPTION"; foreach ($types as $t) { $e = @constant($t); if ($errno & $e) { $className = $t; break; } } throw new $className($errno, $errstr, $errfile, $errline); } } abstract class PHP_Exceptionizer_Exception extends Exception { public function __construct($no = 0, $str = null, $file = null, $line = 0) { parent::__construct($str, $no); $this->file = $file; $this->line = $line; } } class E_EXCEPTION extends PHP_Exceptionizer_Exception {} class E_CORE_ERROR extends E_EXCEPTION {} class E_CORE_WARNING extends E_CORE_ERROR {} class E_COMPILE_ERROR extends E_CORE_ERROR {} class E_COMPILE_WARNING extends E_COMPILE_ERROR {} class E_ERROR extends E_CORE_ERROR {} class E_RECOVERABLE_ERROR extends E_ERROR {} class E_PARSE extends E_RECOVERABLE_ERROR {} class E_WARNING extends E_PARSE {} class E_NOTICE extends E_WARNING {} class E_STRICT extends E_NOTICE {} class E_DEPRECATED extends E_STRICT {} class E_USER_ERROR extends E_ERROR {} class E_USER_WARNING extends E_USER_ERROR {} class E_USER_NOTICE extends E_USER_WARNING {} class E_USER_DEPRECATED extends E_USER_NOTICE {}
- Log in to post comments
- 481 reads