Отслеживание и обработка ошибок
РНР имеет следующие типы ошибок и предупреждений:
Значение | Константа | Описание | |||
1 | E_ERROR | Фатальная ошибка времени исполнения | |||
2 | E_WARNING |
| Предупреждение времени исполнения | ||
4 | E_PARSE | Сообщение интерпретации времени исполнения | |||
8 | E_NOTICE | Простое сообщение времени исполнения | |||
16 | E_CORE_ERROR | Фатальная ошибка при инициализации РНР | |||
32 | E_CORE_WARNING | Предупреждение инициализации | |||
64 | E_COMPILE_ERROR | Фатальная ошибка компиляции | |||
128 | E_COMPILE_ WARNING | Предупреждения компиляции | |||
256 | E_USER_ERROR | Ошибки, определяемые пользователем | |||
512 | E_USER_WARNING | Предупреждения, определяемые пользователем | |||
1024 | E_USER_NOT1CE | Сообщения, определяемые пользователем | |||
2047 | E_ALL | Все перечисленные сообщения |
Указанные значения в виде чисел или консгант можно комбинировать, формируя битовую маску ошибок, о которых необходимо сообщать в ходе исполнения сценария. Для комбинирования используются битовые операторы, но в конфигурационном файле php.ini ' распознаются только «|», «-», «!» и <<&>>.
В PHP 4 по умолчанию разрешены сообщения вида E_ALL & -EJJOTICE, то ость сообщаться должно все, кроме обычных сообщений. Можно переопределить эту установку параметром файла конфигурации еггог_ reporting (ее также можно указывать в файлах конфигурации сервера Apache); а во время исполнения — функцией error_reporting().
Если при вызове функции перед ее именем указать символ «@», то в случае возникновения ошибки в этой функции сообщение о нем выдаваться не будет.
В настоящее время оператор игнорирования ошибок блокирует даже выдачу сообщений о критических ошибках, при возникновении которых сценарий досрочно завершается.
Если разрешен параметр конфигурации track_errors, то сообщение об ошибке сохраняется в глобальной переменной $php_errormsg.
«?php // определенный
пользователем обработчик ошибок
function userErrorHandler (Serrno. Serrmsg.
Sfilenamp Slirenum. Svarb) { $dt = date
("Y-m-d H i:s (Т)"). // время возникновения
ошибки Serrortype = array
( 1 => "Error". 2 => "Warning".
4 => "Parsing Error". 8 => "Notice".
16 => "Core Error". 32 =>
"Core Warning". 64 => "Compile Error".
128 => "Compile Warning". 256 =>
"User Error". 512 => "User Warning".
1024=> "User Notice" );
$err .= "время ($dt). номер ошибки
($errno). ": $err .= "тип ошибки
C'.$errortype[$errno]."): ":
$err = "\"$errmsg\", файл
\"$filename\". строка (".
$err .= $linenum.")\n";
I $user_errors - array
(E_USER_ERROR. E_USER_WARNING.
E_USER_NOTICE): if (in_array($errno.
$user_errors))
echo $err;
// выдать сообщения для ошибок
пользователя // сохранить событие
ошибки в системном журнале
error_log($err. 3.
"/usr/local/php4/error.log"): }
// установить уровень контроля
ошибок и обработчик error_reporting(0)
: // не выводить сообщения РНР
$old_error_handler = set_error_handler
("userErrorHandler");
// неопределенная константа вызывает
предупреждение
$t = _NOT_DEFINED_CONSTANT.
tngger_error("Mos ошибка". E_USER_ERROR);
tngger_error
("Moe предупреждение".
E_USER_WARNING): ?>
Функции обработки ошибок
errorjog
Посылка сообщения об ошибке
int error_log (string message, int message_type [, string destination [, string extra_headers]])
Сообщение, посылаемое этой функцией, может быть направлено в журнал системных сообщений web-сервера, порт TCP или в файл.
В первом аргументе, message, указывается само содержание сообщения; во втором, messagejtype — куда оно должно быть направлено. Назначение обозначается следующими значениями:
Возможные варианты применения функции:
if (!0ra_l_ogon (Susername. Spassword))
{ erroMog ("Сервер Oracle недоступен!".
О). } if (!($foo = allocate_new_foo())
{ rroMog ("Нельзя выделить FOO!".
1. "operator@mydomain.com").
} // other ways of calling error_log():
errorjog ГУ нас ошибка!".
2. "127.0.0 1.7000"); rrorjog
("У нас ошибка1". 2. "loghost");
eri~or_loq ("У нас ошибка!".
3. "/var/tmp/my-errors.log"):
error_reporting
Установка видов сообщаемых ошибок
int errorj-eporting ([int level])
Возвращает предыдущую установку типа сообщаемых ошибок; если указан аргумент, то заново переопределяет ее. В аргументе можно указывать константу, число или битовую маску. Старайтесь использовать константы вместо численных значений, чтобы сохранить совместимость с будущими версиями РНР.
errorj-eporting (2039).
// в РНР 4 эквивалент E_ALL " EJIOTICE
error_reporting (E_ALL * E_NOTICE);
// установка по умолчанию
error_reporting(0):
// отключить сообщения об ошибках
errorj-eporting (EJRROR E_WARNING
| E_PARSE):
/* Общие ошибки выполнения */
error j-eporting (EJRROR | E_WARNING
| E_PARSE | EJIOTICE);
/* также сообщать о неизвестных переменных */
error_reporting (E_ALL).
/* сообщать все ошибки */
set_error_handler
Установка пользовательского обработчика ошибок
string set_error_hand1er (string error_handler)
Функция возвращает имя функции, ранее определенной в качестве обработчика ошибок (или FALSE при ошибке), и устанавливает, в качестве нового обработчика, функцию с указанным в аргументе еггог_ handler именем.
Обычно пользовательский обработчик ошибок работает в паре с функцией tngger_error(), генерирующей ошибку; это может быть использовано (подобно аналогичной конструкции работы с исключениями в С) для освобождения выделенных ресурсов (например, удаления созданных файлов), если сценарий не может нормально завершиться.
Функция, устанавливаемая в качестве обработчика ошибок, должна принимать пять параметров (три последних являются дополнительными и могут не обрабатываться):
<?php // определить константы
пользовательских ошибок define
(FATAL.E_USER_ERROR);
define (ERROR.E_USER_WARNING).
define (WARNING.E_USER_NOTICE).
// установить, какие ошибки должны
обрабатываться в сценарии
errorj-eporting (FATAL | ERROR | WARNING);
// пользовательский обработчик ошибок
function myErrorHandler ($errno. Serrstr.
ierrfile. Serrlme) { switch (Serrno)
{ case FATAL:
echo "<b>Критическая ошибка</b>
[Serrno] $errstr<br>\n";
echo " в строке: Serrline. файла:
".Serrhle:
echo ", PHP ".PHP_VERSION."
(".PHP_OS.")<br>\n":
echo "Aborting...<br>\n":
exit -1:
break case ERROR:
echo "<b>Ошибка</b> [Serrno] $errstr
<br>\n":
break: case WARNING:
echo "<b>Предупреждение</b>
[Serrno] Serrstr<br>\n";
break:
default:
echo "Неизвестный тип ошибки:
[Serrno] $errstr<br>\n";
break; } } // функция для проверки
обработки ошибок (масштабирование
массива) function scale_by_log
(Svect. Sscale) { if ( hs_numenc
(Sscale) || Sscale <= 0 )
trigger_error("вычислить log(x).
для x <= 0 нельзя. ". "(x = Sscale)".
FATAL), if (hs_array(Svect))
{ trigger error("Требуется массив
". ERROR); return null: }
for ($1=0; $i<count(Svect): Si++)
{ if (!is_numenc($vect[$i]))
thgger_error( "Элемент (SI)
не число, и его значением".
" считается О". WARNING);
$temp[Si] = log(Sscale) *
$vect[Si]: } return Stemp: }
// установить пользовательский
обработчик ошибок
Sold_error_handler
= set_error_handler
("myErrorHandler");
Sa = array(2.3."foo".5.5.43.3.21 11);
pnnt_r(Sa).
Sb = scale_by_log(Sa. M_PI);
// здесь выдается предупреждение
echo "Массив, масштабированный
на логарифм(Пи): "; pnnt_r($b):
$с = scale_by_log("not array".2 3);
// здесь ошибка var_dump($c).
$d = scale_by_log($a. -25)
.// здесь критическая ошибка
echo "Продолжение сценария .": ?>
При выполнении сценария вывод будет следующим:
Array ( )[0] => 2 [1] => 3
[2] => too [3] => 5 5 [4] => 43
3 [5] <=> 21 11 )
<b>Прелупреждение</b>
[1024] Элемент (2) не число.
v его значением считается 0<bг>
Массив, масштабированный на
логарифм(Пи) Атау (
[0] => 2.2894597716988
[1J => 3.4341896575482 [2]
»> О [3] => 6 2960143721717 [4
] => 49 566804057279 [5] =>
24 165247890281 )
•Ф>Ошибка</b> Г512]
Требуется массив <br>
NULL <b>Критическая
ошибка</b> [256] вычислить
log(x) для х <= 0 нельзя,
(х --- -2 5)<br> в строке 37.
файла. Е-\ooo\php39.php3.
РНР 4.0.5 (WINNT)<br>
Aborting. . <br>
Не забывайте, что при установке пользовательского обработчика ошибок стандартный обработчик РНР не исполняется. Установки еггог_ reporting() также не будут иметь эффекта, и пользовательский обработчик должен уметь обрабатывать все виды ошибок (значение еггог_ reporting() можно выяснить и действовать соответственно). Заметьте, что код ошибки будет равен 0, если ошибка возникла в функции, выоод ошибок для которой был блокирован оператором «@».
Также помните, что завершать сценарий в обработчике необходимо t явно (например, с помощью функции сhе()), если, конечно, в этом есть необходимость. Если обработчик ошибок завершается с помощью return, то выполнение сценария продолжается с того места, в котором возникла ошибка (то есть исполняются инструкции, которые следуют за той инструкцией, в которой возникла ошибка).
См. также: error_reporting(), restore_error_handier(), trigger_error(), user_error()
error_reporting
Установка видов сообщаемых ошибок
int errorj-eporting ([int level])
Возвращает предыдущую установку типа сообщаемых ошибок; если указан аргумент, то заново переопределяет ее. В аргументе можно указывать константу, число или битовую маску. Старайтесь использовать константы вместо численных значений, чтобы сохранить совместимость с будущими версиями РНР.
errorj-eporting (2039).
// в РНР 4 эквивалент E_ALL " EJIOTICE
error_reporting (E_ALL * E_NOTICE);
// установка по умолчанию
error_reporting(0):
// отключить сообщения об ошибках
errorj-eporting (EJRROR E_WARNING
| E_PARSE):
/* Общие ошибки выполнения */
error j-eporting (EJRROR | E_WARNING
| E_PARSE | EJIOTICE);
/* также сообщать о неизвестных переменных */
error_reporting (E_ALL).
/* сообщать все ошибки */
set_error_handler
Установка пользовательского обработчика ошибок
string set_error_handler (string error_handler)
Функция возвращает имя функции, ранее определенной в качестве обработчика ошибок (или FALSE при ошибке), и устанавливает, в качестве нового обработчика, функцию с указанным в аргументе еггог_ handler именем.
Обычно пользовательский обработчик ошибок работает в паре с функцией tngger_error(), генерирующей ошибку; это может быть использовано (подобно аналогичной конструкции работы с исключениями в С) для освобождения выделенных ресурсов (например, удаления созданных файлов), если сценарий не может нормально завершиться.
Функция, устанавливаемая в качестве обработчика ошибок, должна принимать пять параметров (три последних являются дополнительными и могут не обрабатываться):
<?php // определить константы
пользовательских ошибок define
(FATAL.E_USER_ERROR);
define (ERROR.E_USER_WARNING).
define (WARNING.E_USER_NOTICE).
// установить, какие ошибки должны
обрабатываться в сценарии
errorj-eporting (FATAL | ERROR | WARNING);
// пользовательский обработчик ошибок
function myErrorHandler ($errno. Serrstr.
ierrfile. Serrlme) { switch (Serrno)
{ case FATAL:
echo "<b>Критическая ошибка</b>
[Serrno] $errstr<br>\n";
echo " в строке: Serrline. файла:
".Serrhle:
echo ", PHP ".PHP_VERSION."
(".PHP_OS.")<br>\n":
echo "Aborting...<br>\n":
exit -1:
break case ERROR:
echo "<b>Ошибка</b> [Serrno] $errstr
<br>\n":
break: case WARNING:
echo "<b>Предупреждение</b>
[Serrno] Serrstr<br>\n";
break:
default:
echo "Неизвестный тип ошибки:
[Serrno] $errstr<br>\n";
break; } } // функция для проверки
обработки ошибок (масштабирование
массива) function scale_by_log
(Svect. Sscale) { if ( hs_numenc
(Sscale) || Sscale <= 0 )
trigger_error("вычислить log(x).
для x <= 0 нельзя. ". "(x = Sscale)".
FATAL), if (hs_array(Svect))
{ trigger error("Требуется массив
". ERROR); return null: }
for ($1=0; $i<count(Svect): Si++)
{ if (!is_numenc($vect[$i]))
thgger_error( "Элемент (SI)
не число, и его значением".
" считается О". WARNING);
$temp[Si] = log(Sscale) *
$vect[Si]: } return Stemp: }
// установить пользовательский
обработчик ошибок
Sold_error_handler
= set_error_handler
("myErrorHandler");
Sa = array(2.3."foo".5.5.43.3.21 11);
pnnt_r(Sa).
Sb = scale_by_log(Sa. M_PI);
// здесь выдается предупреждение
echo "Массив, масштабированный
на логарифм(Пи): "; pnnt_r($b):
$с = scale_by_log("not array".2 3);
// здесь ошибка var_dump($c).
$d = scale_by_log($a. -25)
.// здесь критическая ошибка
echo "Продолжение сценария .": ?>
При выполнении сценария вывод будет следующим:
Array ( )[0] => 2 [1] => 3
[2] => too [3] => 5 5 [4] => 43
3 [5] <=> 21 11 )
<b>Прелупреждение</b>
[1024] Элемент (2) не число.
v его значением считается 0<bг>
Массив, масштабированный на
логарифм(Пи) Атау (
[0] => 2.2894597716988
[1J => 3.4341896575482 [2]
»> О [3] => 6 2960143721717 [4
] => 49 566804057279 [5] =>
24 165247890281 )
•Ф>Ошибка</b> Г512]
Требуется массив <br>
NULL <b>Критическая
ошибка</b> [256] вычислить
log(x) для х <= 0 нельзя,
(х --- -2 5)<br> в строке 37.
файла. Е-\ooo\php39.php3.
РНР 4.0.5 (WINNT)<br>
Aborting. . <br>
Не забывайте, что при установке пользовательского обработчика ошибок стандартный обработчик РНР не исполняется. Установки еггог_ reportingO также не будут иметь эффекта, и пользовательский обработчик должен уметь обрабатывать все виды ошибок (значение еггог_ reportingO можно выяснить и действовать соответственно). Заметьте, что код ошибки будет равен 0, если ошибка возникла в функции, выоод ошибок для которой был блокирован оператором «@».
Также помните, что завершать сценарий в обработчике необходимо t явно (например, с помощью функции сhе()), если, конечно, в этом есть необходимость. Если обработчик ошибок завершается с помощью return, то выполнение сценария продолжается с того места, в котором возникла ошибка (то есть исполняются инструкции, которые следуют за той инструкцией, в которой возникла ошибка).
См. также: error_reporting(), restore_error_handier(), trigger_error(), user_error()
restore_error_handler
Восстановление предыдущего обработчика ошибок
void restore_error_handler (void)
Устанавливает в качестве функции обработчика ошибок ту, котораябыла таковой до последнего вызова функции set_error_handler(). Предыдущим обработчиком может быть ранее установленный нользовательский обработчик или встроенный обработчик PUP.
См. также: errorj-eporting(), set_error_handler(), trigger_error(), user_ error().
trigger_error
Генерация ошибки
void trigger_error (string errorjnsg [, int error_type])
Явно вызывает функцию, установленную для обработки ошибок, и обычно используется в паре с обработчиком ошибок (см.: set_ error_handler()). Функция способна генерировать только пользовательские типы ошибок (семейство констант EJJSER), и по умолчанию, если не указан тип ошибки error_type, он считается E_USER_NOTICE.
Возможно конструировать сложные конструкции генерации и обработки ошибок и исключительных ситуаций.
if (assert ($divisor == 0))
trigger_error ("Нельзя делить на 0 ".
E_USER_FRROR)
См. также: error_reporting(), set_error_handler(), restore_error_handler(), user_error().
user_error
Синоним функции trigger_error()
void user_error (string error_msg [, int error_type])