#10. 2 php Перехват ошибок. Регистрация пользовательского обработчика ошибок set_error_handler()

Регистрация нового обработчика ошибок

Функция

string set_error_handler(string $funcName [, int $errorTypes])

позволяет зарегистрировать собственный обработчик ошибок, который будет вызван вместо стандартного обработчика в случае возникновения ошибок заданных в параметре $errorTypes типов (по умолчанию E_ALL).

Значение $errorTypes представляет собой десятичное представление битовой маски, в которой установленные в 1 биты соответствуют конкретным типам ошибок (см. таблицу). Для задания битовой маски, как всегда, можно использовать константы, например:

<?php
set_error_handler("my_handler", E_ALL);

Ошибки, тип которых не соответствует битовой маске, будут обработаны стандартными средствами. При этом нет возможности зарегистрировать одновременно два и более обработчика для различных типов ошибок.

Управление стандартному обработчику передается и в том случае, если пользовательский обработчик возвращает значение false. Если же возвращается любое другое значение или не возвращается ничего, то стандратный обработчик не вызывается.

Ограничения перехватываемых типов ошибок

Перехват ошибок пользовательским обработчиком возможен только для не фатальных, не прерывающих работу скрипта ошибок (warnings, notices), а также для фатальных ошибок с возможностью восстановления.

Таблица

Ошибки
Перехватываемые Неперехватываемые
Не фатальные:
E_WARNING,
E_NOTICE, E_USER_WARNING, E_USER_NOTICE,
E_STRICT, E_DEPRECATED, E_USER_DEPRECATED.
Фатальные ошибки без возможности восттановления:
E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING.
Фатальные с возможностью восстановления:
E_USER_ERROR, E_RECOVERABLE_ERROR.

Вид обработчика

Обработчик ошибок, зарегистрированный с помощью функции set_error_handler(), должен иметь следующий вид:

function my_handler($errno, $msg, $file, $line)
{
     //код обработчика
}

Аргументами являются номер ошибки, текст, имя файла и номер строки, где возникла ошибка.

Восстановление предыдущего пользовательского обработчика

При использовании set_error_handler() предыдущее имя пользовательского обработчика запоминается во внутреннем стеке. Функция restore_error_handler() извлекает предыдущее имя из стека и регистрирует его в качестве текущего обработчика. Если в стеке ничего нет, то текущим назначается стандартный обработчик.

В следующем примере регистрируется обработчик my_handler, который вызывается в случае возникновения (перехватываемой) ошибки внутри функции foo(). После строки вызова функции отключаем обработчик с помощью restore_error_handler().

<?php

function foo()
{
    echo $x; //генерируем ошибку типа E_WARNING
}

function my_handler($errno, $msg, $file, $line)
{
    echo "Ошибка в функции foo(): $msg";   
}

set_error_handler("my_handler", E_ALL);

foo();

restore_error_handler(); //отключаем обработчик

echo $x; //генерируем ошибку и убеждаемся, что будет вызван стандартный обработчик

Результат:

Ошибка в функции foo(): Undefined variable $x
Warning: Undefined variable $x in /var/www/mysite/index.php on line 19