РНР 5 в подлиннике

Страница 339 из 554


Гпава 34. Обработка ошибок и исключения

685

рования диагностического сообщения (его можно потом перехватить при помощи функции-обработчика). Например, функция fopeno при невозможности открытия файла возвращает false; и мы в дальнейшем должны проверить результат на "истинность", как уже неоднократно делали это раньше.

Данный метод имеет три недостатка.

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

□ Любое значение, возвращаемое функцией, может быть по смыслу допустимым. Например, стандартная функция unserialize О распаковывает некоторую переменную из ее строкового представления (сгенерированного вызовом serialize!)) и возвращает ее исходное значение. Что должна вернуть функция в случае ошибки? Если, например, null, то где гарантия, что действительно произошла ошибка, а исходная переменная не содержала просто значение null до упаковки?

□ Код восстановления приходится постоянно дублировать. Например, если нам в программе нужно открыть 10 разных файлов, мы будем вынуждены 10 раз проверить возвращаемое функцией fopeno значение/Легко представить, как сильно это "раздует" программу. Еще хуже вы себя почувствуете, если вспомните, что в будущем может понадобиться модифицировать код восстановления: придется делать это в 10 местах.

Ненормальное состояние программы

Часто одного лишь недопустимого возвращаемого значения оказывается недостаточно для хранения всей информации. Поэтому в дополнение к предыдущему способу в РНР иногда применяется запись информации об ошибке в некоторую внутреннюю переменную, которую можно будет в дальнейшем считать и проанализировать другими функциями. Так работают, например, инструменты для доступа к MySQL в РНР: mysqi_connect {), mysqi_query {) и т. д. Вы можете проверить, не вернули ЛИ фуНКЦИИ "ЛОЖНОе" Значение, а потом ИСПОЛЬЗОВаТЬ mysql_error () или

mysqi_errno {) для получения дополнительной информации.

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

Таким образом, мы вынуждены периодически проверять, не находится ли программа в ненормальном состоянии, и предпринимать дополнительные действия. Это сильно увеличивает код; кроме того, программист может как-нибудь просто забыть вставить в программу требуемые проверки.

Вызов функции-обработчика

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

686

Часть V. Объектно-ориентированное программирование на РНР

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

Механизм обработки исключений или, как чаще всего говорят в мире ООП, просто "исключения" (exceptions) — это технология, позволяющая писать код восстановления после серьезной ошибки в удобном для программиста виде. С применением исключений перехват и обработка ошибок, наиболее слабая часть в большинстве программных систем, значительно упрощается.

Концепция исключений базируется на общей (и достаточно естественной) идее объектно-ориентированного программирования: данные должны обрабатываться в том участке программы, который имеет максимум сведений, как это делать. Если в некотором месте еще не до конца известно, какое именно преобразование должно быть выполнено, лучше отложить работу "на потом". С использованием исключений код обработки ошибки явно отделяется от кода, в котором ошибка может возникнуть.

Исключения также позволяют удобно передавать информацию о возникшей ошибке вниз по дереву (стеку) вызовов функций. Таким образом, код восстановления может находиться даже не в текущей процедуре, а в той, что ее вызывает. Мы поговорим об этой важной особенности в разд. "Раскрутка стека" далее в этой главе.

Базовый синтаксис

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

Любое исключение в программе представляет собой объект некоторого класса, создаваемый, как обычно, оператором new. Этот объект может содержать различную информацию, например, текст диагностического сообщения, а также номер строки и имя файла, в которых произошла генерация исключения. Допустимо добавлять и любые другие параметры.

Прежде чем идти дальше, давайте рассмотрим простейший пример вызова обработчика (листинг 34.2). Заодно получим представление о синтаксисе исключений.

[Листинг 34.2. Файл simple.php

<?php ## Простой пример использования исключений, echo "Начало программы.<Ьг>"; try {

// Код, в котором перехватываются исключения, echo "Все, что имеет начало...<Ьг>";

Исключения




  Hostland.Ru

 «Бесплатный хостинг Hostland.Su» © 2006