В избранное    Домой   

Вторник,  10 Dec 2024 г., 07:12
Слова мудрых, высказанные спокойно, выслушиваются лучше, нежели крик властелина между глупыми. Мудрость лучше воинских орудий; но один погрешивший погубит много доброго. /Екклесиаст/

 Логин:  

 Пароль: 




Анонсы:
=== Дата: 30/09/2011     Автор: Крис Ньюман ===

PHP. Урок 22 Обработка ошибок

Урок 22. Обработка ошибок

В этом уроке вы узнаете, как эффективно обрабатывать ошибки в сценариях PHP и отлаживать сценарии, которые не работают так, как ожидалось.

Система уведомления об ошибках

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

Изменения уровня ошибок

Функция error_reporting позволяет изменить уровень уведомления об ошибках. На вход нужно подать одну из констант в табл. 22.1.

Таблица 22.1. Константы для настройки уровня уведомления

Константа Описание
E_ERROR Сигнализирует о критической ошибке выполнения. Выполнение сценария останавливается
E_WARNING Устанавливает предупреждения во время выполнения. Не критическая, сценарий продолжает выполняться
E_PARSE Сигнализирует об ошибках компиляции
E_NOTICE Показывает замечания во время выполнения. Может указать на потенциальную ошибку
E_CORE_ERROR Сигнализирует о критической ошибке, которая генерируется внутри самого PHP
E_CORE_WARNING Сигнализирует о предупреждении и генерируется внутри самого PHP
E_COMPILE_ERROR Сигнализирует о критической ошибке Zend engine
E_COMPILE_WARNING Сигнализирует о предупреждении Zend engine
E_USER_ERROR Сообщает об ошибках, сгенерированных пользователем при помощи trigger_error
E_USER_WARNING Сообщает об предупреждениях, сгенерированных пользователем при помощи trigger_error
E_USER_NOTICE Сообщает о замечаниях, сгенерированных пользователем при помощи trigger_error
E_ALL Сообщает обо всех ошибках, кроме E_STRICT
E_STRICT Сообщает обо всех ошибках и предупреждениях, включая предложения PHP по изменению кода для улучшения его совместимости

Эти константы можно объединить с помощью поразрядных операторов и создать необходимый набор битов, который установит нужный уровень уведомления. По умолчанию устанавливается уровень E_ALL & E_NOTICE, который показывает все ошибки и предупреждения, кроме E_STRICT. Последний не перекрывается в E_ALL и E_NOTICE.

Чтобы установить уровень уведомления, который показывает все предупреждения и замечания, нужно выполнить следующую команду:

error_reporting(E_ALL);

Предупреждения которые не показываются по умолчанию, не являются критическими и не мешают нормальному выполнению сценария.

Уровень ошибок E_NOTICE может помочь при разработке сценария. Он предупреждает обо всех необъявленных переменных. Кроме того, E_NOTICE не приводит к ошибкам в сценарии. Эти сообщения могут указывать на то, что в названии переменной найдена опечатка и нужно посмотреть ранее набранный код.

Флаг E_NOTICE позволяет проконтролировать стиль кодирования. Например, ключ ассоциативного массива нужно заключать в кавычки. Но небрежный программист может написать $array[kay]. Нужно помнить, что key в PHP является константой. Если она не определена в сценарии, PHP пытается найти переменную с соответствующим текстовым ключом. Но при включенном E_NOTICE появится сообщение об этой двузначности.

Уровень E_STRICT появился в PHP5 и очень помогает писать актуальный код. Он уведомляет об использовании упраздненных функций, которые поддерживаются только для обратной совместимости.

Изменить уровень уведомления можно также в файле php.ini или с помощью .htaccess в нужном каталоге с помощью инструкции error_reporting.

Показ ошибок. Настройки log_errors и display_errors определяют место вывода сообщений об ошибках. Это может быть экран или файл журнала.
На рабочем Web-сайте лучше не выводить сообщения об ошибках на экран. Это небезопасно, т. к. злоумышленник может получить информацию о системе.

Специальный обработчик ошибок

PHP позволяет задать специальную функцию, которая вызывается при обнаружении ошибки. Это позволяет заменить стандартное действие вывода на экран или записи в файл журнала.

Функция set_error_handle задает функцию, которая будет специальным обработчиком ошибок. Ей нужно передать два аргумента. Первый, обязательный — имя функции и второй — необязательный, в котором содержится набор битов, задающий необходимый уровень ошибок. Он и будет о брабатываться этой функцией.

Например, для того, чтобы функция myhandler отслеживала все ошибки E_WARNING и E_NOTICE, используется следующая команда:

set_error_handler(“myhandler”, E_WARNING & E_NOTICE);

Определенный пользователем обработчик ошибок требует два параметра: код ошибки и строку с сообщением об ошибке. Значение кода для ошибки можно взять из табл. 22.1, чтобы знать, какая ошибка произошла. Также можно добавить три необязательных параметра, которые помогут найти ошибку: название файла, номер строки и контекст, в котором произошла ошибка.

В листинге 22.1 задается специальный обработчик ошибок, который записывает все ошибки в таблицу базы данных MySQL.

Листинг 22.1. Специальный обработчик ошибок


<?php
function log_errors($errno, $errstr, $errfile, $erline) {
    $db = mysql_connect("localhost", "loguser", "logpassword");
    mysql_select_db("test", $db);
    $errstr = mysql_escape_string($errstr);
    $sql = "insert into php_log
        (errno, errstr, errfile, errline)
        values
            ('$errno', '$errstr', '$errfile', '$errline')";
    $res = mysql_query($sql, $db);
}
set_error_handle("log_errors");
// Присвоение неопределенной переменной вызовет предупреждение
$a = $b;
?>

Таблицу для сбора ошибок можно создать с помощью следующего SQL-выражения:

CREATE TABLE php_log (
    error_timestamp timestamp,
    errno int,
    errstr text,
    errfile text,
    errline int
);

Нужно помнить, что в этом примере не используется пятый необязательный параметр для контекста. Контекст передается в виде массива. В нем содержится значение каждой переменной, включая локальные и системные суперглобальные, которые определены в сценарии на момент, когда случилась ошибка.

Эта информация может пригодиться при отладке, но ее слишком много, чтобы хранить в файле журнала или таблице. Кроме того, так как значение передается в виде массива, $errcontext нужно сначала передать в функцию serialize, чтобы сохранить в таблице или текстовом файле.

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

Генерирование ошибки

Можно воспользоваться функцией trigger_error, чтобы при необходимости сгенерировать ошибку. Если задан специальный обработчик ошибок, он и будет обрабатывать пользовательскую ошибку.

Иначе ее обработкой займется стандартный обработчик ошибок PHP. Нужно передать строку с ошибкой в trigger_error. Также можно добавить необязательную константу типа ошибки. Если ее не задать, будет использована E_USER_NOTICE.

Например, для генерирования пользовательского замечания можно воспользоваться следующим кодом:

trigger_error("Случилась какая-то ошибка");

На экране появится ошибка похожая на эту:

Notice: Случилась какая-то ошибка in /home/chris/error.php on line 3

Чтобы сгенерировать критическую ошибку с аналогичным текстом, используется следующие выражение:

trigger_error("Случилась какая-то ошибка", E_USER_ERROR);

Типы ошибок. Для пользовательских ошибок нужно использовать E_USER_ERROR и E_USER_WARNING, а не E_ERROR и E_WARNING. Тип E_USER_ERROR тоже трактуется как критическая ошибка и завершает выполнения сценария сразу после обнаружения.

Сохранение ошибок

С помощью функции error_log можно удовлетворить все простые потребности по хранению ошибок. Эта функция позволяет записывать ошибки в файл журнала Web-сервера или любой другой, отправлять их по электронной почте или пересылать на удаленный сервер отладки.

Функции error_log передаются следующие аргументы:

error_log($message, $message_type, $destination, $extra_headers);

Только аргумент message является обязательным. Стандартным действием является запись сообщения в файл журнала PHP. В большинстве случаев это будет файл журнала Web-сервера.

Аргумент message_type задает тип отправки сообщения. Возможные значения перечислены в табл. 22.2.

Таблица 22.2. Значения message_type для error_log

Значения Описание
0 Сообщение записывается в стандартный файл журнала Web-сервера
1 Сообщение отправляется по электронной почте. В параметре distination содержится ящик адресата, a extra_headers позволяет задать дополнительные заголовки письма
2 Сообщение отправляется на удаленный сервис отладки. Параметр destination содержит адрес сервера. Отметим, что удаленная отладка не поддерживается, начиная с PHP 4 и выше
3 Сообщение добавляется в конец локального файла. Параметр destination содержит имя файла и путь

Например, для отправки сообщения об ошибке по электронной почте используется следующие выражение:

error_log("В сценарии произошла ошибка", 1,
      "chris@lightwood.net",
      "From: PHP-сценарий ошибки ");

Подавление ошибок и предупреждений

PHP позволяет подавлять сообщения об ошибках в сценарии. Можно полностью отключить показ ошибок или выбрать отдельные команды, для которых не будут показываться ошибки.

Оператор подавления ошибки

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

Например, если при соединении с базой данных MySQL произошел сбой, PHP генерирует собственную ошибку. Но может быть также и альтернативная проверка соединения. Например, проверка идентификатора соединения с базой данных. В следующим примере используется символ @, который блокирует вывод ошибок PHP. Таким образом, в случае ошибки появится только специальное сообщение:

$db = @ mysql_connect("localhost", "username", "password");
if (!$db) {
    echo "Не удалось соединиться с базой данных";
    exit;
}

Можно поместить символ @ перед любым выражением в PHP. Он подавляет все сообщения об ошибках, которые произошли во время выполнения выражения.

В этом примере подавляется выражение, которое выполняет соединение с базой данных. Общее правило таково: если что-то в PHP может иметь значение, перед ним следует поставить символ @. Нельзя размещать символ @ перед управляющими конструкциями языка. Например, перед определением функции или условным выражением.

Анализ ошибок. Оператор @ не скрывает ошибок, которые обнаружены на стадии анализа кода сценария.

Следующие выражение — правильное. Но кажется, что сообщение об ошибке относится к mysql_connect:

@ $db = mysql_connect("localhost", "username", "password");

Подавление ошибок. Если в сценарии используется set_error_handler для установки специального обработчика ошибок, оператор @ не оказывает никакого эффекта.

Предотвращение показа ошибок

Если директиве настройки display_errors из файла php.ini установить значение Off, это предотвращает вывод всех сообщений об ошибках на экран.

При отключении вывода ошибок на экран, нужно активизировать директиву log_errors. Все шибки будут сохраняться в файл журнала. Иначе будет невозможно узнать о потенциальных угрозах на сайте. Не нужно выключать display_errors на стадии разработки Web-сайта.

Резюме

В этом уроке вы узнали, как обнаружить и обработать ошибку в сценарии PHP. В следующем уроке вы научитесь настраивать PHP для конкретных потребностей.


<<назад

Погода в Рудне
(Волгоградcкая обл.)

Подробнее >>


Курс валют
на 10 Дек 2024 г.
704 - Вьетнамских донгов
- 1