Учебник по основам PHP. PHPBeginner

Отслеживание и обработка ошибок


РНР имеет следующие типы ошибок и предупреждений:

Значение Константа Описание
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 — куда оно должно быть направлено. Назначение обозначается следующими значениями:

  • 0 — сообщение заносится в системный журнал событий (файл) согласно установке параметра конфигурации error_log;


  • 1 — сообщение отправляется по электронной почте, по адресу, указанному в аргументе destination. Это единственный тип сообщения, использующий четвертый параметр, extrajieaders, в котором можно указать дополнительные заголовки (как в функции Mail());


  • 2 — сообщение посылается через подключение отладки. Это возможно только в случае, если параметр удаленной отладки был разрешен в файле конфигурации. Для этого также должен быть определен адрес хоста (имя или его адрес IP) и порт сокета, который будет принимать сообщения отладки; это можно указать в аргументе destination или параметрах конфигурации;


  • 3 — message добавляется в конец файла destination.


  • Возможные варианты применения функции:

    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])


    Содержание раздела