Вот я задавал вопрос на данную тему на ru.SO
Ошибки и исключения. Что когда использовать и как?В чем же отличие, как я для себя решил. (в прочем, это мое решение совпадает с документацией php и со
статьей на хабре.)
Error - ошибка - это ошибка скрипта, которую вызвал сбой системы или непредвиденные действия злого (или очень "хитроумного") пользователя. Хороший пример - опечатка в коде (ошибка парсинга) или невозможность подключиться к базе данных (ошибка работы с бд.). Ошибку ДОЛЖЕН исправить разработчик, поэтому ошибки можно и НУЖНО логировать и слать уведомления на почту разработчику, если такое приключилось.
Exception - исключение - это исключительная ситуация, которую я, как разработчик, предвидел. Т.е. я знаю, что эта ситуация будет непременно возникать в коде вновь и вновь, и мне просто иначе нужно на нее реагировать. Говорят "выбросить исключение". Т.е. заставить программу работать в этой ситуации иначе. Хороший пример - деление на ноль. Я знаю, что такое будет возникать. Когда пользователь разделит на ноль, то результат будет неопределен (или равен бесконечности) - об этом я сообщаю пользователю. Никакого логирования здесь не нужно. И уж тем более никаких мэйлов разработчику.
Исключением так же может являться любая неосновная ветка работы моего скрипта. Например, мой скрипт должен отдать пользователю какие-то данные, но пришло сообщение, что пользователь уже в них не нуждается (он передумал) - вот тебе исключение. Т.е. я прекращаю собирать данные и никуда их не отправляю (хотя основная идея моего скрипта - отправлять данные). Мне больше ничего не нужно делать. Все. Мне здесь не нужны никакие логи. Максимум, что я могу - это записать для статистики, сколько же раз всего пользователи соизволили отказаться от информации. Просто чтоб знать. Это другой механизм и его ни в коем случае нельзя путать с ошибками, которые, еще раз повторю, НУЖНО ИСПРАВЛЯТЬ.
Теперь ближе к коду. Давайте пройдемся по мануалу:
Обработкой ошибок в php занимается встроенный механизм. Когда случается ошибка (сбой системы) - этот механизм адекватно на нее реагирует: завершает выполнение скрипта, если ошибка критична, и продолжает его, если она несущественна. Все. Здесь же есть смысл записать ошибку в логи и отправить уведомление разработчику, что ему нужно ИСПРАВИТЬ код. ЛИКВИДИРОВАТЬ ошибку. Скрипт при возникновении ошибки может так же выбросить исключение (о боже!), если выставлена соответствующая настройка в php.ini или при помощи директивы error_reporting(E_ALL). Это делают
разработчики, чтоб проще было
ИСПРАВЛЯТЬ ошибки во время кодирования. На работающем сайте все сообщения об ошибках, которые генерирует встроенный обработчик ДОЛЖНЫ БЫТЬ ВЫКЛЮЧЕНЫ. Для пользователя на сайте
НЕТ ошибок. Ошибки есть ТОЛЬКО ДЛЯ РАЗРАБОТЧИКА. Для пользователя на сайте есть только ИСКЛЮЧЕНИЯ. Т.е. запланированные реакции скрипта на возникшую ситуацию.
Что мы можем делать при помощи исключений? Да все что угодно. В том числе и реагировать каким то заранее запланированным образом на возникшую ошибку.
Ну и, наконец, самое главное. Копипаст из мануала, как работают те или иные функции в php:
1. set_error_handler(пользовательская функция) — Задает определенный пользователем обработчик ошибок. Т.е. разработчик решает добавить логирование в случае возникновения ошибки и отправить пользователю вместо чистого листа (заготовленного php на этот случай) красивую страничку, что мол извините, что-то пошло не так, попробуйте ка вот эту ссылку. (статус HTTP ответа 500)
2. set_exception_handler(пользовательская функция) — Задает пользовательский обработчик исключений - эта функция задает обработчик по умолчанию для случаев, когда исключение выброшено вне блока try/catch. Т.е. решает проблему его существования (для twin-а)
3. trigger_error(сообщение, статус генерируемой ошибки) — Вызывает пользовательскую ошибку/предупреждение/уведомление - тут нужно уточнить, что предупреждение и уведомление - это виды некритичных ОШИБОК. (E_USER_WARNING, E_USER_NOTICE)
4. throw new Exception('Сообщение, которое хотим передать обработчику исключений'); можно использовать в связке с set_exception_handler() без блока try catch.
Так что все твои, twin, надуманные преимущества от незнания. Сам это понял вот недавно (хотя думал, что понимаю уже давно). Нет ничего стыдного в том, что кто-то чего-то не знает. Я еще очень многого не знаю. Нам всем еще многое предстоит узнать, понять, осмыслить.
_____________
Youtube канал WebDeveloper->Run()Сайт для душиGitter