ресурс для начинающих веб-разработчиков
комплексные веб-услуги по созданию сайтов

Справочный материал по основным языкам программирования и верстки сайтов.

Готовая методика создания простых и сложных динамичных сайтов, с использованием PHP и MySQL.

Использование веб-редактора Adobe Dreamweaver в разработке сайтов.

Использование графических редакторов Adobe Flash, Adobe Photoshop, Adobe Fireworks в подготовке веб-графики.

Разработка веб-сайтов под "ключ".

Разработка отдельных фрагментов сайтов, консультации по вопросам верстки веб-страниц и веб-программирования.

Обработка исключений. Концепции обработки ошибок

Концепции обработки ошибок

Исключения — это новые и важные компоненты РНР5, представляющие универсальный механизм расширяемой, удобной для обслуживания и объектно-ориентированной обработки ошибок.

Концепция обработки ошибок

Основная идея обработки ошибок состоит в выполнении кода внутри так называемого блока try. Этот блок представляет собой раздел кода следующего вида:

try

{

//здесь находится необходимый код

}

В случае возникновения непредвиденных ситуаций внутри блока try можно выполнить так называемую генерацию исключения. В РНР исключения нужно генерировать вручную. Это выполняется следующим образом:

throw new Exception ('сообщение ', код);

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

Конструктор этого класса принимает два параметра: сообщение и код. Они служат для представления сообщения об ошибке и номера ошибки. Оба эти параметра необязательны.

И наконец, за блоком try должен следовать как минимум один блок catch, который выглядит подобно показанному ниже:

catch (указание_типа исключения)

{

// обработка исключения

}

Объект, передаваемый в блок catch (и перехватываемый им), является тем, который передается (и генерируется) оператором throw, генерирующим исключение. Исключение может быть любого типа, однако удобнее всего использовать либо класс Еxception, либо экземпляры собственных пользовательских исключений, унаследованных от класса Еxception.

В случае возникновения исключения код РНР ищет соответствующий блок catch. При наличии более одного блока catch передаваемые в них объекты должны иметь различные типы, чтобы РНР мог определить, какой именно блок catch соответствует конкретному случаю.

Еще один заслуживающий внимания момент связан с возможностью генерирования дополнительных исключений внутри блока catch.

Рассмотрим простой пример обработки исключений:

<?php
try
{
throw new Exception ('Возникла очень серьезная ошибка', 42);
}
catch (Exception $e)
{
echo 'Исключение '. $e -> getCode(). ': '. $e -> getMessage() . ' в ' . $e -> getFile(). ', строка '. $e ->getLine(). '<br>';
}
?>

Результат выполнения кода показан ниже на рисунке.

Блок catch выводит сообщение об ошибке с указанием места ее возникновения

Из листинга видно, что мы воспользовались несколькими методами класса Exception, которые будут рассмотрены позже. В приведенном примере кода было сгенерировано исключение класса Exception. Методы этого встроенного класса можно использовать в блоке catch для вывода полезного сообщения об ошибке.

Класс Exception

PHP5 поставляется со встроенным классом Exception. Как уже упоминалось, конструктор этого класса принимает два параметра: сообщение об ошибке и номер ошибки.

Кроме конструктора, этот класс содержит следующие встроенные методы:

  • getCode() — возвращает код, переданный конструктору;
  • getVessage() — возвращает сообщение, переданное конструктору;
  • getFile() — возвращает полный путь файла кода, в котором возникло исключение;
  • getLine() — возвращает количество строк в файле кода, в котором возникло исключение;
  • getTrace() — возвращает массив, содержащий информацию отслеживания места возникновения исключения;
  • getTraceAsString() — возвращает ту же информацию, что и метод getTrace, но сформированную в виде строки;
  • __toString() — позволяет упростить вывод с помощью echo объекта Exception, предоставляя всю информацию, полученную из перечисленных методов.

Как видите, в коде листинга были использованы четыре из этих методов. Эту ж еинформацию (плюс информацию отслеживания) можно было бы получить с помощью оператора:

echo $e;

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

Исключения, определяемые пользователем

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

Конструкция throw позволяет передавать любые другие объекты. иногда такая потребность может возникнуть при наличии проблем, связанных с каким-то конкретным объектом, и необходимости его передачи в целях отладки.

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

Класс Exception — компоненты класса, которые можно наследовать

<?php
class Exception {
function __construct (string $message = NULL, int $code = 0)
{
if (func_num_args())
{
$this -> message = $message;
}
$this -> code = $code;
$this -> file = __FILE__;//из конструкции throw
$this -> line = __LINE__;//из конструкции throw
$this -> trace = debug_backtrace();
$this -> string = StringFormat($this);
}
protected $message = 'Unknown exception';//сообщение исключения
protected $code = 0; //определяемый пользователем код исключений
protected $file; // исходное имя файла
protected $line; //исходная строка исключения

private $trace; //информация отслеживания
private $string; //только для внутреннего пользования!!

final function getMessage()
{
return $this -> message;
}

final function getCode()
{
return $this -> code;
}
final function getFile()
{
return $this -> file;
}
final function getTrace()
{
return $this -> trace;
}
final function getTraceAsString()
{
return self::TraceFormat($this);
}
function __toString()
{
return $this -> string;
}
static private function StringFormat(Exception $exception)
{
//... недоступная в РНР-сценариях функция,
//которая возвращает всю необходимую информацию в виде строки
}
static private function TraceFormat(Exception $exception)
{
// ... недоступная в РНР-сценариях функция,
//которая возвращает всю информацию отслеживания в виде строки
}
}
?>

Основная причина, по которой было приведено определение класса, состоит в том, что большинство общедоступных методов являются финальными: то есть, их нельзя перекрыть. Можно создать собственный субкласс Exceptions, но нельзя менять поведение базовых методов. Вместе с тем, можно перекрывать функцию __toString(), чтобы изменить способ отображения исключения. Можно также добавлять собственные методы.

Пример определенного пользователем класса Exception user_defined_exception.php

<?php
class myException extends Exception
{
function __toString()
{
return '<table border><tr><td><strong>Исключение '. $this -> getCode(). '</strong>: '.$this -> getMessage(). '<br>'.'в '
.$this-> getFile(). ', строка '. $this-> getLine()
.'</td></tr></table><br>';
}
}
try
{
throw new myException('Произошла очень серьезная ошибка ', 42);
}
catch (myException $m)
{
echo $m;
}
?>

Результат выполнения кода показан на рисунке.

Класс myException обеспечивает 'изящный вывод' сообщений об исключениях

В этом коде объявляется новый класс исключения с именем myException, расширяющий класс Exception. Различие между этим классом и классом Exception связано с заменой метода __toString() для обеспечения более "изящного" вывода сообщения об исключении.

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