Передовой опыт: обработка ошибок и исключений в php
Об этой серии:
В этой серии мы рассмотрим, какие передовые методы должен соблюдать веб-разработчик при создании кода PHP или управлении им.
Дезинфекция, проверка и побег
Безопасность и управление паролями
Обработка ошибок и исключений
Введение
21 октября 1879 г., 19:15:13
Менло-Парк, Нью-Джерси
Сильный ветер вечером охлаждает,
погода в последнее время не радовала, и последние 2 недели непрерывно лил дождь, и, похоже, он не собирается прекращаться в ближайшее время.
на фабрике несколько человек работают как черти над чем-то, что может изменить мир, каким они его знают.
Окончательное испытание произойдет через несколько минут и станет результатом нескольких недель исследований, напряженной работы и расчетов.
3
2
1
ПОП!!
Фонарик освещает комнату на секунду, затем снова темно, еще один день прошел, еще один неудачный, еще одна ошибка.
Это уже 9999-й.
«Я не потерпел неудачу. Я только что нашел 10 000 способов, которые не работают».
Томас Эдисон
Если вы когда-либо слышали мотивационных ораторов, таких как Брайан Трейси, Тони Робин, Зиг Зиглар или Джим Рон, вы знаете, что у всех них есть проблемы с тем, как школы работают по всему миру.
В университетах и колледжах ошибки скорее наказываются, чем приветствуются.
Однако в реальном мире ошибки — единственный способ стать лучше.
Особенно это касается веб-разработки.
Метод проб и ошибок, безусловно, лучший способ стать великим и отточить свое мастерство.
Верно и то, что нам нужно быть осторожными и обращать внимание на ошибки, которые мы совершаем.
Причина совершения ошибок в том, что мы можем управлять ими и учиться на них.
PHP упрощает обработку, управление и изучение ошибок, которые могут возникнуть в вашем коде.
Как управлять ошибками в PHP 7
Если вы спросите меня, какие функции больше всего улучшились между PHP 5.6 и PHP 7 или PHP 7.1, я обязательно поставлю обработку ошибок на первые 3 позиции.
Седьмая версия нашего любимого языка программирования принесла нам интерфейс с определенной целью:
его нужно было легко реализовать и использовать во многих случаях.
Бросаемый интерфейс,
на самом деле, может быть реализован как классом обоих типов (класс ошибки и исключение), так и поставкой и несколькими методами, которые мы можем использовать, чтобы лучше понять и проанализировать нашу ошибку.
Здесь вы можете увидеть класс и то, как вы можете его использовать:
Throwable {
abstract public getMessage ( void ) : string
abstract public getCode ( void ) : int
abstract public getFile ( void ) : string
abstract public getLine ( void ) : int
abstract public getTrace ( void ) : array
abstract public getTraceAsString ( void ) : string
abstract public getPrevious ( void ) : Throwable
abstract public __toString ( void ) : string
}
Try {
} catch (Throwable $e) {
echo "an instance of class Throwable has been caught";
}
В приведенном выше фрагменте показаны все методы, которые вы можете использовать для отладки ошибки PHP в вашем скрипте (с большим количеством подсказок типа)
и фактический код, который вы можете использовать, чтобы попробовать блок кода и выдать ошибку или исключение.
Ошибки, ошибки везде!
Тот, кто имел дело с ошибкой до PHP 5.6, знает, какой это была боль и с какой головной болью ему приходилось иметь дело на этапе отладки.
Раньше внутри движка возникали ошибки, и вы могли бы справиться с этим, если бы они не были фатальными ошибками.
Вам также нужно было учитывать, что ошибки и исключения — это две совершенно разные вещи в вашем коде, и это добавило еще один уровень сложности в и без того сложную ситуацию.
Начиная с PHP 7, фатальные ошибки приводят к возникновению исключения ошибки и вы можете легко управлять не фатальными ошибками с помощью специальных методов
Я могу, например, запустить некоторый код и выдать ошибку только в случае фатальной ошибки.
try {
echo $thisVariableIsNotSet;
inexistentFunctionInvoked();
} catch (Error $e) {
echo "Error: $e->getMessage()";
}
Потерпите, пока я объясню, что происходит:
В нашем псевдокоде мы должны указать переменную и функцию, оба не определены таким образом, unser или несуществующие.
PHP обрабатывает неустановленную переменную иначе, чем неопределенная функция,
первая — просто недопустимая переменная, ошибка уведомления, веб-разработка работает много часов, это может случаться часто,
вторая ошибка вместо этого является реальной функцией, возможно, в ней есть какая-то важная логика.
Вот почему в PHP неопределенная функция — серьезная проблема, фатальная ошибка.
Наличие этих двух строк кода в блоке try позволяет catch создавать экземпляр класса Error (переменная $е).
e_ реализует интерфейс _Throwable_, что означает, что он может использовать все методы, которые вы видели в предыдущем абзаце. Следовательно, _e->getMessage();
Создание собственного обработчика ошибок
Могут быть случаи, когда возникают некоторые ошибки, не относящиеся к классу Error.
Если эти ошибки не являются фатальными, PHP позволяет вам, как разработчику, определять специальные функции и обрабатывать их так, как вы предпочитаете.
Для этого нужно использовать set_error_handle() функция.
Эта функция принимает либо строку с именем функции, которую вы хотите использовать, либо массив, содержащий объект и имя метода, который вы вызываете.
Функция может остановить скрипт,
если вы не хотите, чтобы он продолжался или возвращал значение и продолжался, когда код вызывал функцию в первую очередь.
Давайте посмотрим на практичный, но простой пример ниже.
set_error_handle() не может управлять фатальной ошибкой, а это значит, что для ее проверки нам нужно смоделировать предупреждение (подойдет и деление на ноль),
затем мы определим содержимое функции и перехватим ошибку, когда она произойдет.
function myErrorHandler($errno, $errstr, $errfile, $errline) {
echo "An error occurred in line {$errline} of file {$errfile} with message {$errstr}";
}
set_error_handler("myErrorHandler");
try {
5 / 0;
} catch (Throwable $e) {
echo $e->getMessage();
}
Не забывайте, что вы хотите скрыть ошибки от производственной среды, когда возникает ошибка, она должна быть видна только на локальном или промежуточном сервере.
На самом деле, показ ошибки в продакшене может дать серьезный намек на уязвимость вашего сайта для хакера или злоумышленников.
Для этого вы можете отредактировать 3 параметра в вашем php.ini.
- display_errors если установлено значение false, он будет подавлять ошибки;
- log_errors сохранять ошибки в файл журнала;
- Отчет об ошибках настраивает, какие типы ошибок вызывают отчет;
Функции обработки ошибок
В PHP есть несколько функций, которые могут облегчить обработку ошибок и простых задач. В этом разделе вы найдете краткое описание каждой из них.
- debug_backtrace() он принимает несколько параметров, таких как флаг опций и число, которое ограничивает результаты и генерирует сводку о том, как ваш скрипт попал туда, где он есть, он делает это, возвращая переменную массива;
- debug_print_backtrace() работает аналогично предыдущему, но вместо создания массива трасс печатает их в обратном хронологическом порядке;
- error_get_last() возвращает ассоциативный массив, содержащий информацию о последней ошибке, возникшей в скрипте;
- error_clear_last() сбросить внутренний журнал ошибок PHP, если он используется до error_get_last(), последний вернет null;
- журнал_ошибок() он требует обязательного сообщения в качестве параметра и отправляет его в определенные процедуры обработки ошибок;
- отчет об ошибках() Эта функция требует в качестве параметра либо none, либо константы ошибок (полный список вы можете найти здесь) и устанавливает уровень точности, который должен иметь PHP-приложение при обработке ошибок;
- set_error_handler() а также set_Exception_обработчик() установить специальные функции, которые обрабатывают ошибки и исключения;
- обработчик_обработчика_ошибок() а также обработчик_обработчика_исключений() он используется после set_error_handler() и set_exception_handler(). Он направлен на возврат обработчика к предыдущему обработчику ошибок. Это может быть встроенная или определенная пользователем функция;
- trigger_ошибка() эта функция вызывает ошибку, принимая сообщение в качестве обязательного параметра и флаг error_type в качестве произвольного;
- user_ошибка() псевдоним trigger_ошибка();
Что такое исключения
Исключения — это относительно новые функции PHP, они были реализованы только в PHP 5, но быстро стали основной частью любого скрипта объектно-ориентированного программирования.
Исключения — это состояния скриптов, требующие особого обращения, поскольку скрипт не работает должным образом.
И Errors, и Exception — это просто классы, которые реализуют Метательный интерфейс.
Как и любой другой класс в мире ООП, он может быть расширен,
который позволяет создавать иерархии ошибок и настраивать способ обработки исключений.
На что следует обратить внимание и что может привести к ошибкам и недоразумениям, так это то, что вы не можете объявить свой собственный класс, а затем решить генерировать исключения.
Единственные классы, которые могут выдать ошибку, это те, которые реализуют Метательный учебный класс.
Давайте поиграем в игру, посмотрим на код и ответим на следующий вопрос.
class MainException extends Exception {}
class SubException extends MainException {}
try {
throw new SubException("SubException thrown");
} catch (MainException $e) {
echo "MainException thrown" . $e->getMessage();
} catch (SubException $e) {
echo "SubException thrown" . $e->getMessage();
} catch (Exception $e) {
echo "Exception thrown" . $e->getMessage();
}
Какое исключение выбрасывается?
В приведенном ниже примере выдается исключение Подисключениеон наследуется от Основное исключение который расширяет Исключение.
Блок оценивается от первого (того, что сверху) до последнего, и когда исключение соответствует имени заданного класса, оно запускается.
Это выше можно считать лучшей практикой, потому что мы сужаем сообщение, которое хотим показать, и в конечном итоге.
Если ни один из наших классов не подходит, мы используем исключение класса PHP для общей проверки.
Перехват нескольких исключений одновременно
До сих пор мы видели несколько попыток с несколькими уловами.
Каждый блок кода повторяет сообщение с разными ошибками,
Подумайте, на случай, если мы создадим дюжину разных исключений,
мы должны добавить дюжину блоков catch? А что, если мы хотим одинаково обрабатывать несколько типов ошибок?
Чтобы справиться с этой ситуацией, PHP предоставил ключевое слово pipe « | ”;
Вот пример того, как его использовать:
class MainException extends Exception {}
class SubException extends Exception {}
try {
throw new SubException;
} catch (MainException | SubException $e) {
echo "Exception thrown: " . get_class($e);
}
Наконец ключевое слово
Я уверен, что вы уже видели условную структуру switch-case в прошлом,
если нет, я получил целую статью об условных операторах в PHP.
Одним из элементов оператора switch является то, что если ни один из случаев не будет оценен, в конечном итоге будет запущен блок «по умолчанию», если он присутствует.
Команда try a catch позволяет сделать что-то похожее на ваш код, указав ключевое слово finally
try {
$handle = fopen("c:\\folder\\resource.txt", "r");
throw new Exception("Exception thrown");
} catch (Exception $e) {
echo "Exception thrown" . $e->getMessage();
} finally {
fclose ( resource $handle );
}
Обычно это ключевое слово используется, как показано в примере выше, когда нам нужно закрыть файл, который мы ранее открыли внутри блока try.
Вы должны помнить, что код внутри блока finally всегда выполняется, даже если исключения были выброшены ранее в сценарии.
Но вы можете использовать его всякий раз, когда считаете, что это поможет вашему делу.
Если вы считаете, что эта статья была полезной, и хотите узнать больше о передовом опыте в PHP, щелкните изображение ниже.
Вывод
Томас Эдисон происходил из скромного происхождения, и исторические данные подтверждают, что он не был самой блестящей личностью.
Как бы то ни было, его способность окружать себя творческими и увлеченными людьми, а также способность глубоко анализировать и учиться на своих ошибках сделали его одним из лучших изобретателей, когда-либо живших, и, безусловно, одним из самых богатых и знаменитых людей своей эпохи.
Без колебаний могу сказать, что мы, веб-разработчики, можем сделать то же самое.
Возможно, мы никогда не изобретем всемирно известное приложение или не изменим жизнь миллиардов людей с помощью нашего веб-сайта, но нет сомнений, что, учась на своих ошибках, мы будем повышать свои навыки намного быстрее.
Управление ошибками является фундаментальной частью этого.
Узнайте, как правильно это сделать, и освойте все возможности, доступные в PHP и его компонентах, таких как PHPUnit и Sentry, которые упростят эту задачу для каждого из нас.
Полезные компоненты или веб-сайт, которые вы можете использовать для управления своей ошибкой прямо сейчас:
филп/возгласы
нетте/трейси
видео / псалом
Себастьянбергманн/phpunit
кодецепция / кодецепция
getsentry/sentry
https://phpcodechecker.com
https://www.piliapp.com/php-syntax-check