Этот урок связан с проектом PHP исключения

Исключения PHP. Часть 2 из 2

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

 

Расширенные исключения

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

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

class UserException extends Exception
{
   public function __construct($error_code)
   {
      parent::__construct(UserErrors::getErrorMessage($error_code), $error_code);
      Logger::newMessage($this);
   }
}

Мы переписали функцию __construct для реализации нашего собственного конструктора. Так как наш класс расширяет класс Exception, то мы можем использовать его конструктор с помощью директивы parent. Сделав так, мы можем отказаться от генерации сообщения об ошибке каждый раз при выбрасывании исключения, и использовать только код исключения. Также можно опустить запись в журнал, так как пользовательский конструктор автоматически будет заносить все исключения в журнал.

Обновим код для использования нашего нового класса UserException:

private static function _validateUserId($user_id)
{
   if( !is_numeric($user_id) && $user_id != 'error' ) {
      throw new UserException(UserErrors::INVALIDID);
   }
   return $user_id;
}

Так как исключение автоматически заносит себя в журнал, можно Полевой игрок поймал исключение: опустить данную операцию в блоке try-catch:

...
...
} catch( Exception $e ) {
   echo "Полевой игрок поймал исключение: #{$e->getCode()}";
   //Logger::newMessage($e);
}

Теперь изменим код в других местах класса  User, где ожидается появление исключений.

Класс User:

...
...
...
public function __get($value) {
   $value = "_{$value}";
   if( !isset($this->$value) ) {
      throw new UserException(UserErrors::NOTASETTING);
   }
   return $this->$value;
}
 
public function __set($name, $value) {
   switch($name) {
      case 'user_id':
         $user_id = self::_validateUserId($value);
         $this->_user_id = $user_id;
         break;
 
      case 'user_email':
         $user_email = self::_validateUserEmail($value);
         $this->_user_email = $user_email;
         break;
 
      case 'user_password':
         $user_password = self::_validateUserPassword($value);
         $this->_user_password = $user_password;
         break;
 
      default:
         throw new UserException(UserErrors::NOTASETTING);
         break;
   }
   return true;
}
 
private static function _getUserRecord($user_id)
{
   ...
   ...
   ...
   switch($user_id) {
      ...
      ...
      ...
      default:
         throw new UserException(UserErrors::DOESNOTEXIST);
         break;
   }
}

И попробуем генерировать три исключения:

$user = new User(1);
try {
   $user->user_email = 'invalid email';
} catch( Exception $e ) {
   echo "Полевой игрок поймал исключение: #{$e->getCode()}<br />";
}
 
try {
   echo $user->setting_that_doesnt_exist;
} catch( Exception $e ) {
   echo "Полевой игрок поймал исключение: #{$e->getCode()}<br />";
}
 
try {
   //id пользователя не существует
   $user = new User(3);
} catch( Exception $e ) {
   echo "Полевой игрок поймал исключение: #{$e->getCode()}<br />";
}

Ну и какие выгоды сулит расширенное исключение, кроме пользовательского конструктора? Такое улучшение можно легко реализовать с помощью класса Exception без дополнительных действий. Но с помощью пользовательских исключений мы можем:

  • Переписать функцию __construct и реализовать собственный код;
  • Организовать исключение в зависимости от типа объекта;
  • использовать блок множественных перехватов для обработки исключений в зависимости от типа!

 

Блок множественных перехватов

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

Наш блок try-catch предназначен для обработки обычного типа исключений Exception — так обеспечивается обработка ошибок для исключений незапланированных типов.

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

try {
   $user = new User(1);
   $user->user_password = '123';
} catch( UserException $e ) {
   echo "Полевой игрок поймал исключение UserException: #{$e->getCode()}<br />";
} catch( Exception $e ) {
   echo "Полевой игрок поймал исключение Exception:: #{$e->getCode()}<br />";
}
 
try {
   //Использование аргумента 'error' в классе User имитирует 
   //ошибку в библиотеке SQL
   $user = new User('error');
} catch( UserException $e ) {
   echo "Полевой игрок поймал исключение UserException: #{$e->getCode()}<br />";
} catch( Exception $e ) {
   echo "Полевой игрок поймал исключение Exception:: #{$e->getCode()}<br />";
}


Исключения UserException и Exception будут обрабатываться по-разному. Может показаться, что пользы в раздельной обработке нет. Но самое очевидное применение - показ пользователю или запись в журнал только определенных исключений.

 

Заключение

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

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: net.tutsplus.com/tutorials/php/the-ins-and-outs-of-php-exceptions/
Перевел: Сергей Фастунов
Урок создан: 21 Октября 2011
Просмотров: 20762
Правила перепечатки


5 последних уроков рубрики "PHP"

  • Фильтрация данных с помощью zend-filter

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

  • Контекстное экранирование с помощью zend-escaper

    Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.

  • Подключение Zend модулей к Expressive

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

  • Совет: отправка информации в Google Analytics через API

    Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.

  • Подборка PHP песочниц

    Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.

или авторизуйтесь, чтобы добавлять комментарии, оценивать уроки и сохранять их в личном кабинете
  • 21 Октября 2011 10:05
    Slonoritsar
    это все конечно круто, но думаю, не всегда стоит пользоваться исключениями - я обычно использую
    or die()
    и то только при отладке скрипта. А так, конечно, приму к сведению.
  • 22 Октября 2011 18:28
    Slonoritsar
    кстати, еще нарыл на сайте подобное, но по-меньше объемом: http://ruseller.com/lessons.php?rub=37&id=945
  • 25 Октября 2011 23:50
    Илья Ковалевский
    А я реально считаю, что это дикий бред. Использовал их только когда писал движ для блога, и то для удобного взаимодействия девелопера и движка...
^ Наверх ^