Учебное пособие: Обработка ошибок в коде программ РНР

echo "</div>";

}

// Регистрируем ее для всех типов ошибок.

set_error_handler("myErrorHandler", E_ALL);

// Вызываем функцию для несуществующего файла, чтобы

// сгенерировать предупреждение, которое будет перехвачено.

filemtime("spoon");

?>

Теперь при возникновении любой ошибки или даже предупреждения в программе будет вызвана функция myErrorHandier(). Ее аргументы получат значения, соответственно, номера ошибки, текста ошибки, имени файла и номера строки, в которой было сгенерировано сообщение.

К сожалению, не все типы ошибок могут быть перехвачены таким образом. Например, ошибки трансляции во внутреннее представление E_PARSE, а также E_ERROR немедленно завершают работу программы. Вызовы функции die()также не перехватываются.

Назначить функцию реакции на E_PARSE и E_ERRORвсе же можно. Дело в том, что перехватчик выходного потока скрипта, устанавливаемый функцией ob__start(), обязательно вызывается при завершении работы программы, в том числе в случае фатальной ошибки. Конечно, ему не передается сообщение об ошибке и ее код; он должен сам получить эти данные из "хвоста" выходного потока (например, используя функции для работы с регулярными выражениями).

В случае если пользовательский обработчик возвращает значение false (и только его!), считается, что ошибка не была обработана, и управление передается стандартному обработчику РНР (обычно он выводит текст ошибки в браузер). Все остальные возвращаемые значения (включая даже null или, что то же самое, в случае, если оператора return вообще нет), приводят к подавлению запуска стандартной процедуры обработки ошибок.

2.2 ФУНКЦИЯrestore_error_handler()

void restore_error_handler()

Когда вызывается функция set_error_handler(), предыдущее имя пользовательской функции запоминается в специальном внутреннем стеке РНР. Чтобы извлечь это имя и тут же его установить в качестве обработчика, применяется функция restore_error_handler().Пример:

// Регистрируем обработчик для всех типов ошибок.

set_error_handler("myErrorHandler", E_ALL);

// Включаемподозрительныйфайл.

include "suspicious_file.php";

// Восстанавливаем предыдущий обработчик.

restore_error_handler();

Необходимо следить, чтобы количество вызовов restore_error_handler() было в точности равно числу вызовов set_error_handler().Нельзя восстановить то, чего нет.

2.3 ПРОБЛЕМЫ С ОПЕРАТОРОМ @

Пользовательская функция перехвата ошибок вызывается вне зависимости от того, был ли использован оператор подавления ошибок в момент генерации предупреждения. Это очень неудобно: поставив оператор @ перед вызовом filemtime(), мы увидим, что результат работы скрипта нисколько не изменился: текст предупреждения по-прежнему выводится в браузер.

Для того чтобы решить проблему, воспользуемся полезным свойством оператора @: на время своего выполнения он устанавливает error_reporting, равным нулю. Значит, мы можем определить, был ли вызван оператор @ в момент "срабатывания" обработчика, по нулевому значению функции error_reporting() (при вызове без параметров она возвращает текущий уровень ошибок) — листинг 2.3.

Листинг 2.3. Файл handler.php

<?php ## Перехват ошибок и предупреждений.

// Определяем новую функцию-обработчик.

functionmyErrorHandler($errno, $msg, $file, $line) {

// Если используется @, ничего не делать.

if (error_reporting() == 0) return;

К-во Просмотров: 388
Бесплатно скачать Учебное пособие: Обработка ошибок в коде программ РНР