#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
- 822 reads