Преобразование ошибок в исключения. Библиотека PHP_Exceptionizer
Не совсем понимаю, что делает свойство класса $catcher->prevHdl. А конкретно вот эта часть кода.
if ($this->prevHdl) {
// Если предыдущий обработчик существует, вызываем его.
$args = func_get_args();
call_user_func_array($this->prevHdl, $args);
}
Ведь $catcher->prevHdl хранит результат выполнения функции set_error_handler(). Чего мы добиваемся, вызывая call_user_func_array($this->prevHdl, $args);, еще и с аргументами метода handler().
<?php ## Класс для преобразования ошибок 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;
// Признак, нужно ли игнорировать остальные типы ошибок, или же
// следует использовать стандартный механизм обработки PHP.
public $ignoreOther = false;
// Предыдущий обработчик ошибок.
public $prevHdl = null;
// Функция-обработчик ошибок PHP.
public function handler($errno, $errstr, $errfile, $errline)
{
if (!error_reporting()) return;
// Перехватчик НЕ должен обрабатывать этот тип ошибки?
if (!($errno & $this->mask)) {
// Если ошибку НЕ следует игнорировать...
if (!$this->ignoreOther) {
if ($this->prevHdl) {
// Если предыдущий обработчик существует, вызываем его.
$args = func_get_args();
call_user_func_array($this->prevHdl, $args);
} else {
// Иначе возвращаем false, что вызывает запуск встроенного
// обработчика PHP.
return false;
}
}
// Возвращаем true (все сделано).
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",
);
// Формируем имя класса-исключения в зависимости от типа ошибки.
$className = __CLASS__ . "_" . "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;
}
}