Главная страница » Статьи и уроки » PHP статьи » PHP: Обработка исключений
Опрос
Какие статьи добавлять?
Выделенные и виртуальные серверы в Европе

PHP: Обработка исключений

Автор: administrator Дата: 22-12-2014, 01:18 Категория: Статьи и уроки / PHP статьи
Все пользователи Сети знают, как порой неприятно открывать страницу и видеть вместо долгожданной статьи/блога/картинки некий маловразумительный текст, сообщающий об ошибке сервера. К сожалению, реальность Интернет такова, что очень сложно сделать скрипт, одинаково хорошо работающий на любой платформе и при любых настройках сервера.

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

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

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


Исключения - это какие-либо аварийные ситуации, возникающие при выполнении скрипта. В PHP исключение можно сгенерировать ("выбросить", "вызвать") и поймать его. Исключение может сенерироваться как интерпретатором, так и разработчиком.

Вызов исключения производится следующим образом:

<?php
    throw new Exception('My exception message');
?>

Перехват исключения осуществляется с помощью конструкции try...catch. В общем виде эта конструкция записывается так:

<?php
    try  {
        // код, который может выбросить исключение
    } catch(Exception $ex) {
        //$ex - экземпляр класса Exception
        // или его наследника
    }
?>

Стоит отметить, что блоков catch может быть много, по одному на каждый класс перехватываемых исключений. Таким образом можно создать фильтр исключений, т.е. перехватывать не все, а только избранные типы исключений, а все остальные будут перехвачены стандартным обработчиком PHP.

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

Законный вопрос - зачем самому вызывать ошибку? Рассмотрим простой пример - есть функция формирования отчёта о деятельности компании. Эта функция содержит несколько сотен строк кода, вызывает ещё десяток функций и читает данные из баз данных и файлов. Теперь представим ситуацию, когда одна из баз данных вдруг отключилась, а мы об этом узнали лишь в середине процедуры. Раз нет данных, то и формировать отчёт нет смысла - он будет неполным и некорректным. Но как прервать выполнение основной функции, одновременно сообщив подробности ошибки? Можно сделать с помощью нескольких if..else, но более простым решением будет использование исключений.

<?php

// Класс для записи в лог-файл тех исключений,
// которые не требуют моментальной реакции администратора
class ExceptionWriter extends Exception
{
    publuc void Write()
    {
        // записываем содержимое ошибки в лог-файл
    }
}

// Класс для отправки на email всех исключений,
// о которых администратор должен узнать немедленно
class ExceptionMailer extends Exception
{
    publuc void Send()
    {
        // отсылаем содержимое ошибки на email админа
    }
}

try
{
    //...
    // код подключения необходимых данных
    //...

    if(!$connected)
        trow new ExceptionMailer('Источники данных не подключены!');

    //...
    // код обработки данных
    //...

    if(!$template_present)
        trow new ExceptionWriter('Файл шаблона не найден.');

    //...
    // код обработки шаблона и генерации отчёта
    //...
}
catch(ExceptionWriter $ew)
{
    $ew->Write();
}
catch(ExceptionMailer $em)
{
    $em->Send();
}
catch(Exception $ex)
{
    echo 'Исключение: ' . $ex->getMessage();
}
?>

В этом примере мы объявляем два наследника от класса Exception и выполняем генерацию отчёта. Первым делом мы подключаем все нужные источники данных (базы данных, файлы и пр). Если хотя бы один источник не подключился - продолжать работу нельзя и нужно предупредить администратора об ошибке. Поэтому генерируем исключение типа ExceptionMailer. Если подключение прошло успешно - продолжаем работу, обрабатываем данные и генерируем отчёт на основе шаблона. Если шаблон не найден - генерируем соответствующее исключение.

В рассмотренном примере важную роль играет порядок catch, точнее порядок проверки на тип исключения. Если первым поставить Exception, то все остальные исключения никогда не сработают, т.к. конструкция catch(Exception $ex) перехватывает абсолютно все доступные исключения.

PHP позволяет использовать свой обработчик исключений. Для этого необходимо объявить собственную функцию обработки и зарегистрировать её при помощи функции set_exception_handler().

<?php

function special_handler($exception) {
    echo "log: " . $exception->getMessage() . "\n";
}
set_exception_handler('special_handler');
throw new Exception('Пример исключения');
?>

После этого все возникающие исключения, не обрамлённые конструкцией try...except, будут передаваться в объявленную вами функцию. Например, можно изменить функцию, чтобы она писала все исключения в файл и выдавала пользователю в браузер "красивое" сообщение об ошибке сервера:

<?php
   function special_handler($exception) {
      // добавляем описание исключения в лог-файл
      $file = fopen("logfile.log", "a+");
      fwrite($file, $exception->getMessage() . "\n");
      fclose($file);

      // выводим пользовалелю понятное сообщение
      echo "Обнаружена ошибка сервера. Попробуйте ".
            "войти позже. Приносим свои извинения.";
  }
?>

Иногда эта функция бывает очень удобной, особенно в процессе отладки скриптов непосредственно на сервере. Если выводить исключения как обычно в браузер - их смогут увидеть посетители, а это не прибавит популярности вашему сайту. Гораздо менее болезненно пользователи воспримут сообщение типа "Извините, сервер находится на обслуживании, попробуйте войти позже.". Поэтому все ошибки и исключения необходимо писать в файлы, а лучше ещё и отправлять администратору на email.

Хорошим тоном при создании сайтов считается полное отсутствие ошибок. Если же ошибки возникают - они должны быть обработаны и представлены пользователю и разработчику в понятном виде.
  • 0
Просмотров: 1 617 Напечатать Жалоба
Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь. Мы рекомендуем Вам зарегистрироваться либо зайти на сайт под своим именем.
Написать комментарий
Ваше Имя:
Ваш E-Mail:
  • bowtiesmilelaughingblushsmileyrelaxedsmirk
    heart_eyeskissing_heartkissing_closed_eyesflushedrelievedsatisfiedgrin
    winkstuck_out_tongue_winking_eyestuck_out_tongue_closed_eyesgrinningkissingstuck_out_tonguesleeping
    worriedfrowninganguishedopen_mouthgrimacingconfusedhushed
    expressionlessunamusedsweat_smilesweatdisappointed_relievedwearypensive
    disappointedconfoundedfearfulcold_sweatperseverecrysob
    joyastonishedscreamtired_faceangryragetriumph
    sleepyyummasksunglassesdizzy_faceimpsmiling_imp
    neutral_faceno_mouthinnocent

Введите два слова, показанных на изображении: