Обработка ошибок PHP

ADS

Иногда все идет не так, как надо. Файлы где-то потерялись, серверы баз данных остались не инициализированы, URL-адреса изменились, XML-файлы поврежде­ны, права доступа настроены неправильно, лимиты на дисковую память превыше­ны. Этот список можно продолжать до бесконечности. В стремлении предусмот­реть любую проблему, простой метод может иногда утонуть под тяжестью собст­венного кода обработки ошибок.

Вот определение простого класса Conf, который сохраняет, извлекает и опреде­ляет данные в XML-файле конфигурации.

class Conf {

private $file;

private $xml;

private $lastmatch;

function construct( $file ) {

$this->file = $file;

$this->xml = simplexml load file($file);

}

function write (){

file_put_contents(

$this->file, $this->xml->asXML() );

function get( $str ) {

$matches = $this->xml->xpath(,,/conf/item{@name=\,,$str\»} «) ;

if ( count( $matches ) ) {

$this->lastmatch = $matches{0};

return (string)$matches{0};

}

return null;

}

function set( $key, $value ) {

if ( ! is_null( $this->get( $key ) ) ) {

$this->lastmatch{0}=$value;

return;

}

$conf = $ thi s->xml->conf;

$this->xml->addChild(‘item’, $value)->addAttribute( ‘name’, $key );

В классе Conf для доступа к парам «имя/значение» используется расширение РНР SimpleXml. Ниже приведен фрагмент файла конфигурации в формате XML, с которым работает наш класс.

<?xml version=»l.0П?>

<conf>

citem name=»user»>bob</item> </item name=»pass»>newpass</item> </item name=»host»>localhost</item> </conf>

Конструктору класса Conf передается имя файла конфигурации. которое далее передается функции simplexml_load_file(). Полученный от функции объект типа SimpleXml Element сохраняется в свойстве $xml. В методе get () для нахожде­ния элемента item с заданным атрибутом name используется метод xpath объекта

SimpleXmlElement. Значение найденного элемента возвращается в вызывающий код. Метод set () либо меняет значение существующего элемента, либо создает но­вый. И наконец, метод write () сохраняет данные о новой конфигурации в исход­ном файле на диске.

Как и многие коды, приведенные в качестве примеров, код класса Conf крайне упрощен. В частности, в нем не предусмотрена обработка ситуаций, когда файл конфигурации не существует или в него нельзя записать данные. Этот код также слишком «оптимистичен». В нем предполагается, что XML-документ должен быть правильно отформатирован и содержать ожидаемые элементы.

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

  1. Мы можем завершить выполнение программы. Это простой, но радикальный выход. В результате наш скромный класс будет виноват в том, что из-за него потерпел неудачу весь сценарий. Хотя такие методы, как____ construct () и write (), удачно расположены в коде с целью обнаружения ошибок, у них нет информации, позволяющей решить, как обрабатывать эти ошибки.
  2. Вместо обработки ошибки в классе, мы можем вернуть признак ошибки в том или ином виде. Это может быть булево или целое значение, например О или -1. В некоторых классах можно также сформировать текстовое сообще­ние об ошибке или набор специальных признаков, чтобы клиентский код мог запросить больше информации в случае неудачного завершения про­граммы.

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

Проблема заключается в том, что возвращаемое значение может быть запорче­но. В РНР нет средств, заставляющих возвращать унифицированное значение. На данный момент в РНР не поддерживались уточнения типа для возвращаемого класса, поэтому ничто не может нам помешать вернуть признак ошибки вместо ожидаемого объекта или значения элементарного типа. Делая так, мы должны полагаться на то, что клиентский код будет проверять тип возвращае­мого объекта после каждого вызова нашего метода, подверженного ошибкам. А это довольно рискованно. Никому нельзя доверять!

Когда мы возвращаем ошибочное значение вызывающему коду, нет никакой гарантии, что клиентский код будет «вооружен» лучше нашего метода и сможет решить, как обрабатывать ошибку. А если не сможет, то проблемы будут появлять­ся снова и снова. Клиентский метод должен будет определить, как реагировать на ошибочную ситуацию, и, возможно, даже реализовать другую стратегию сообще­ния об ошибке.

Советую прочитать также

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

Перед отправкой формы: