Исключения PHP. Часть 1 из 2
Этот урок связан с проектом PHP исключения
Все еще возвращаете false, когда функция в вашей программе обнаруживает ошибку? В данной серии из двух уроков мы рассмотрим исключения PHP, и как их использовать для обработки ошибок в ваших приложениях.
Что такое исключения?
Исключения являются специальными условиями, обычно в случае ошибки, которые проявляются или могут быть специально созданы программой. Они указывают на то, что что-то в процессе отличается от предполагаемого хода событий. В большинстве случаев подобные ситуации требуют выполнения специальных инструкций, чтобы предотвратить неконтролируемое завершение процесса.
Как работают исключения?
Исключения могут быть брошены (thrown)
и пойманы (caught)
. Когда исключение брошено, то значит, произошло что-то выходящее за рамки нормального течения процесса работы программы, и требуется выполнение какой-то другой функции. Подхват исключения осуществляется в специальной функции, которая сообщает остальной программе о том, что она готова обработать исключение.
Для объяснения действия исключений очень хорошо подходит аналогия с бейсболом.
- Питчер (браузер) бросает мяч кетчеру.
- Отбивающий игрок пытается попасть по мячу. Если ему не удается отбить мяч, то он получает страйк. А если удается, то полевой игрок может поймать мяч.
- Если полевой игрок ловит мяч, у него есть два варианта действий. Если он достаточно далеко от отбивающего, то может передать мяч другому полевому игроку. А если до отбивающего небольшое расстояние, то полевой игрок может кинуть мяч в него и тем самым вывести его из игры.
Бросок питчера кэтчеру в модели исключения похож на нормальное течение процесса. Но если отбивающий игрок попадет по мячу, происходит исключительная ситуация.
Ловля мяча полевым игроком похожа на выполнение функции try-catch
для обработки исключения. Функция try-catch
может самостоятельно выполнить нужные действия, или перебросить исключение другой функции.
Как использовать исключения
Сформировать обработку исключений в PHP очень просто. Так как исключения являются частью стандартной библиотеки PHP(SPL), они входят в ядро PHP, начиная с версии 5. То есть исключения уже ждут, когда их начнут использовать.
Исключения реализуются также как и любой другой объект:
$exception = new Exception(); throw $exception;
Так же как и любой объект, они имеют методы, которые можно вызвать. Данные методы облегчают формирование реакции на исключение. Например, функция getMessage()
позволяет получить сообщение об ошибке, которое может быть записано в журнал или выведено в браузер.
Вот список методов исключений:
getMessage()
– получает сообщение исключения;getCode()
– возвращает числовой код, который представляет исключение;getFile()
– возвращает файл, в котором произошло исключение;getLine()
– возвращает номер строки в файле, где произошло исключение;getTrace()
– возвращает массив backtrace() до возникновения исключения;getPrevious()
– возвращает исключение, произошедшее перед текущим, если оно было;getTraceAsString()
– возвращает массив backtrace() исключения в виде строки;__toString()
–возвращает все исключение в виде строки. Данную функцию можно переписать.
Для лучшей иллюстрации методов, создадим класс User
, который осуществляет базовое управление записями пользователей:
<?php class User { protected $_user_id; protected $_user_email; protected $_user_password; public function __construct($user_id) { $user_record = self::_getUserRecord($user_id); $this->_user_id = $user_record['id']; $this->_user_email = $user_record['email']; $this->_user_password = $user_record['password']; } //Данные функции сформируем позже public function __get($value) {} public function __set($name, $value) {} private static function _getUserRecord($user_id) { //Для урока будем использовать модель записи для представления передачи данных в базу $user_record = array(); switch($user_id) { case 1: $user_record['id'] = 1; $user_record['email'] = ' Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript '; $user_record['password'] = 'i like croissants'; break; case 2: $user_record['id'] = 2; $user_record['email'] = ' Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript '; $user_record['password'] = 'me too!'; break; case 'error': //имитируем неизвестное исключение от какой-нибудь используемой библиотеки SQL: throw new Exception('Ошибка библиотеки SQL!'); break; } return $user_record; } } ?>
В данном примере имеется несколько мест, где может проявиться исключение. Для начала, $user_id в нашей функции _getUserRecord()
должен иметь тип integer. Если события сложатся по другому, то нужно генерировать исключение:
... ... ... private static function _getUserRecord($user_id) { $user_id = self::_validateUserId($user_id); ... ... ... } private static function _validateUserId($user_id) { if( !is_numeric($user_id) && $user_id != 'error' ) { throw new Exception('Ой! Здесь что-то не так с идентификатором пользователя'); } return $user_id; }
Теперь попробуем создать пользователя с неправильным идентификатором:
$user
=
new
User(1);
$user2
=
new
User(
'not numeric'
);
В итоге мы получим системное сообщение об ошибке.
А теперь позволим полевому игроку поймать исключение и обработать его:
try { //Сначала создаем пользователя с номером один $user = new User(1); //Затем намеренно делаем ошибку $user2 = new User('not numeric'); } catch( Exception $e ) { echo "Полевой игрок поймал исключение: {$e->getMessage()}"; }
То есть, когда мы ловим исключение, то можно избежать ужасного сообщения об ошибке, формируемого PHP по умолчанию.
Нужно помнить, что когда появляется исключение, оно останавливается только в том случае, если функция try-catch
может его поймать. Иначе оно остается не пойманным и будет карабкаться по стеку вызовов, что в конечном итоге приведет к выводу сообщения об ошибке в браузере. Рассмотрим, где в нашем примере было брошено исключение.
- Создаем новый объект
User
в строке$user2 = new User('not numeric');
- Выполняем функцию
__construct()
классаUser
- Переходим к функции
_getUserRecord()
классаUser
- Проверяем
$user_id
с помощью функции_validateUserId
- Если
$user_id
не является числовым значением, выбрасываем объект исключения.
Мы также можем выполнить функцию getTraceAsString()
для отслеживания исключения:
... ... } catch( Exception $e ) { echo "Полевой игрок поймал исключение: {$e->getMessage()}"; echo '<pre>'; echo $e->getTraceAsString(); echo '</pre>'; }
То есть, не смотря на то, что исключение произошло гораздо глубже вызова $user2 = new User('not numeric')
, оно вскарабкалось наверх, пока блок try-catch
не обработал его.
Теперь сформируем наше исключение для использования кода. Соответствие числового кода исключению является хорошим способом скрыть ошибку от клиента. По умолчанию, код исключения 0
. Но мы можем изменить его при создании исключения:
... ... ... if( !is_numeric($user_id) ) { throw new Exception('Ой! Здесь что-то не так с идентификатором пользователя', UserErrors::INVALIDID); } ... ... ...
Обязательно нужно создать класс UserErrors:
class UserErrors { const INVALIDID = 10001; const INVALIDEMAIL = 10002; const INVALIDPW = 10003; const DOESNOTEXIST = 10004; const NOTASETTING = 10005; const UNEXPECTEDERROR = 10006; public static function getErrorMessage($code) { switch($code) { case self::INVALIDID: return 'Ой! Здесь что-то не так с идентификатором пользователя'; break; case self::INVALIDEMAIL: return 'Адрес email неправильный!'; break; case self::INVALIDPW: return 'Пароль меньше 4 символов!'; break; case self::DOESNOTEXIST: return 'Пользователя не существует!'; break; case self::NOTASETTING: return 'Таких установок нет!'; break; case self::UNEXPECTEDERROR: default: return 'Какая-то ошибка!'; break; } } }
Теперь мы можем модифицировать обработчик исключений для вывода кода исключения вместо показа сообщения.
... ... } catch( Exception $e ) { echo "Полевой игрок поймал исключение: #{$e->getCode()}"; }
Теперь будем использовать другие методы исключения для его отслеживания. Сначала создадим класс Logger
:
class Logger { public static function newMessage( Exception $exception, $clear = false, $error_file = 'exceptions_log.html' ) { $message = $exception->getMessage(); $code = $exception->getCode(); $file = $exception->getFile(); $line = $exception->getLine(); $trace = $exception->getTraceAsString(); $date = date('M d, Y h:iA'); $log_message = "<h3>Информация об исключении:</h3> <p> <strong>Дата:</strong> {$date} </p> <p> <strong>Сообщение:</strong> {$message} </p> <p> <strong>Код:</strong> {$code} </p> <p> <strong>Файл:</strong> {$file} </p> <p> <strong>Строка:</strong> {$line} </p> <h3>Stack trace:</h3> <pre>{$trace} </pre> <br /> <hr /><br /><br />"; if( is_file($error_file) === false ) { file_put_contents($error_file, ''); } if( $clear ) { $content = ''; } else { $content = file_get_contents($error_file); } file_put_contents($error_file, $log_message . $content); } }
Модифицируем обработку исключения, чтобы использовать класс Logger
:
... } catch( Exception $e ) { echo "Полевой игрок поймал исключение: #{$e->getCode()}"; Logger::newMessage($e); }
Теперь при выполнении программы будет выводиться код исключения, а в файле exceptions_log.html
будет представлена информация о месте появления исключения.
Заключение
В данном уроке представлены базовые сведения об исключениях PHP. В следующем уроке серии мы рассмотрим расширенное исключение и множественные блоки catch
.
Источник: http://feedproxy.google.com/~r/ruseller/CdHX/~3/hskMVWVgn_w/lessons.php
Дайджест новых статей по интернет-маркетингу на ваш email
Новые статьи и публикации
- 2024-11-26 » Капитан грузового судна, или Как начать использовать Docker в своих проектах
- 2024-11-26 » Обеспечение безопасности ваших веб-приложений с помощью PHP OOP и PDO
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-15 » Перенос сайта на WordPress с одного домена на другой
- 2024-11-08 » OSPanel 6: быстрый старт
- 2024-11-08 » Как установить PhpMyAdmin в Open Server Panel
- 2024-09-30 » Как быстро запустить Laravel на Windows
- 2024-09-25 » Next.js
- 2024-09-05 » OpenAI рассказал, как запретить ChatGPT использовать содержимое сайта для обучения
- 2024-08-28 » Чек-лист: как увеличить конверсию интернет-магазина на примере спортпита
- 2024-08-01 » WebSocket
- 2024-07-26 » Интеграция с Яндекс Еда
- 2024-07-26 » Интеграция с Эквайринг
- 2024-07-26 » Интеграция с СДЕК
- 2024-07-26 » Интеграция с Битрикс-24
- 2024-07-26 » Интеграция с Travelline
- 2024-07-26 » Интеграция с Iiko
- 2024-07-26 » Интеграция с Delivery Club
- 2024-07-26 » Интеграция с CRM
- 2024-07-26 » Интеграция с 1C-Бухгалтерия
- 2024-07-24 » Что такое сторителлинг: техники и примеры
- 2024-07-17 » Ошибка 404: что это такое и как ее использовать для бизнеса
- 2024-07-03 » Размещайте прайс-листы на FarPost.ru и продавайте товары быстро и выгодно
- 2024-07-01 » Профилирование кода в PHP
- 2024-06-28 » Изучаем ABC/XYZ-анализ: что это такое и какие решения с помощью него принимают
- 2024-06-17 » Зачем вам знать потребности клиента
- 2024-06-11 » Что нового в работе Яндекс Метрики: полный обзор обновления
- 2024-06-11 » Поведенческие факторы ранжирования в Яндексе
- 2024-06-11 » Скорость загрузки сайта: почему это важно и как влияет на ранжирование
Великие умы обсуждают идеи, средние - обсуждают поступки, а малые - людей Индийская пословица |
Мы создаем сайты, которые работают! Профессионально обслуживаем и продвигаем их , а также по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.