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

p{ "title": "Обработка ошибок в PHP 2026: кто, зачем и как выбирает стратегию | Платформа обучения веб-разработке", "keywords": "обработка ошибок PHP, исключения PHP, try catch, error handler, buyer segments, выбор стратегии, веб-разработка обучение, уровни обработки ошибок, PHP 8, логирование ошибок", "description": "Практическое руководство по обработке ошибок в PHP. Разбор трёх сегментов разработчиков: юниоры, продакшн-инженеры, легаси-миграторы. Инструменты и сценарии для каждого.", "html_content": "

Обработка ошибок в PHP — не абстрактная тема, а конкретный выбор инструмента под свою задачу. В 2026 году у веб-разработчика есть три принципиально разных подхода: базовая обработка через try/catch, глобальные обработчики set_error_handler/set_exception_handler и доменные исключения для бизнес-логики. Выбор зависит от того, кто вы — юниор, продакшн-инженер или разработчик, работающий с легаси. Ниже разберём три сегмента аудитории, их цели и точные критерии, по которым каждый выбирает свою стратегию.

Первый сегмент — начинающие разработчики (стаж до 1 года) и студенты профильных курсов. Их главная цель — не допустить фатального падения скрипта на локальной машине и научиться читать stack trace. Для них оптимальна классическая пара try/catch + finally. Они не пишут код для продакшна, поэтому им не нужны продвинутые обработчики. Основной инструмент — try/catch с базовым логированием в файл через error_log(). Рекомендуемый параметр для начала: ловить только Throwable, а не конкретные Exception, чтобы не пропустить ошибки типов и аргументов. Пример: обработка PDOException при подключении к БД — ловить, логировать сообщение и показывать пользователю общее «Ошибка соединения».

Второй сегмент — продакшн-инженеры с опытом от двух лет. Они работают с реальными проектами, где нагрузка — тысячи запросов в минуту. Их задача — не просто поймать ошибку, а залогировать её с контекстом (URI, IP, сессия) и отправить в агрегатор (Sentry, Bugsnag, ELK). Для этого используется комбинация set_error_handler (преобразует все ошибки PHP в ErrorException) и set_exception_handler (ловит неперехваченные исключения). Внутри этих обработчиков пишется код записи в Monolog с уровнем ERROR или CRITICAL. Например: Monolog с обработчиком RotatingFileHandler, размер файла 10 MB, количество ротаций — 30 дней. Или отправка через Guzzle в Sentry с тегами «project_id» и «php_version». Критически важный параметр — не использовать die() или exit() внутри обработчика, а вернуть HTTP-ответ 500 и пустое тело.

Критерии выбора стратегии для юниоров

Юниор выбирает подход по трём критериям: простота реализации, минимальный код и возможность отладки. Если в проекте используется PDO — обязательно обернуть все запросы в try/catch. Если работают с файловым вводом-выводом — ловить ErrorException. Пример кода для юниора: try { $dbh = new PDO($dsn); } catch (PDOException $e) { error_log($e->getMessage()); echo 'Ошибка БД'; }. Не рекомендуется использовать global catch без finally, так как ресурсы (соединения) остаются открытыми. Конкретный параметр: в finally закрывать дескрипторы и соединения — $stmt->closeCursor() или $dbh = null.

Стратегия для продакшн-инженеров: глобальные обработчики и агрегация

Для команды из 3–5 разработчиков, работающих над одним проектом, единая система логирования критична. В 2026 году стандарт — PSR-3 (Monolog) с транспортами в Sentry или Graylog. Конкретный алгоритм: 1) В bootstrap-файле (обычно index.php) установить error_reporting(E_ALL). 2) Через set_error_handler преобразовать все ошибки в ErrorException. 3) Через set_exception_handler отправлять исключения в Monolog с контекстом: $_SERVER['REQUEST_URI'], $_SERVER['REMOTE_ADDR'], сессионный ID. 4) Для прод-среды отключить вывод ошибок в браузер: ini_set('display_errors', '0'). 5) Настроить уровни: WARNING — для ошибок ввода-вывода, ERROR — для SQL и API, CRITICAL — для сбоев кэша. Размер лога — 100 MB, автоудаление старых записей за 90 дней. Пример из реального проекта: интеграция с Sentry через официальный SDK, отправка события с уровнем error и дополнительным тэгом «env: production».

Миграция легаси: как перевести проект с PHP 5 на PHP 8

Разработчик, сопровождающий легаси-проекты, сталкивается с конфликтом: старый код использует trigger_error() и die(), а новый требует исключения. Решение — глобальный перехват через set_error_handler, который для E_WARNING, E_NOTICE, E_USER_ERROR генерирует ErrorException. Важный параметр: второй аргумент set_error_handler — типы ошибок, которые нужно перехватывать. Для легаси лучше указать E_ALL | E_STRICT, чтобы не пропустить ни одной. После преобразования все старые ошибки становятся исключениями, которые можно ловить в одном try/catch на уровне маршрутизатора. Пример: в старом проекте было 150 мест с trigger_error. После внедрения обработчика все они превратились в исключения, которые перехватываются в едином блоке и логируются с именем файла и номером строки. Дополнительно — использовать ErrorException вместо Exception, чтобы сохранить severity (уровень) оригинальной ошибки. В 2026 году этот подход применяется в 70% проектов на миграции.

Ключевые отличия обработки ошибок в PHP 8 (2026)

В PHP 8 появилась атрибутная валидация (атрибут #[SensitiveParameter]), которая не влияет на обработку ошибок напрямую, но меняет формат сообщений в stack trace. Разработчику нужно обновить парсеры логов, чтобы корректно обрабатывать скрытые параметры. Второе отличие — строгая типизация: TypeError теперь выбрасывается чаще, и его тоже нужно ловить. Третье — атрибут #[Deprecated] для функций, которые в будущем могут быть удалены. Для продакшн-инженера это означает, что нужно добавить в обработчик проверку на E_DEPRECATED и отправлять в отдельный канал (например, Monolog->channel('deprecations')). Никогда не используйте @ (оператор подавления ошибок) в новом коде — он устарел и не работает с ErrorException. Вместо него используйте try/catch с конкретным типом исключения. Пример кода: try { $result = file_get_contents($url); } catch (ValueError $e) { $result = ''; }. Это даёт полный контроль и логирование.

Дополнительный совет для всех сегментов: не смешивайте логику бизнес-ошибок (неверный пароль) с техническими (сбой БД). Для бизнес-ошибок создавайте доменные исключения (например, ValidationException), которые наследуются от \Exception. Их ловите в контроллере и возвращаете HTTP 422. Технические исключения (PDOException, ErrorException) должен ловить глобальный обработчик и возвращать 500. Критерий для разделения: если ошибка вызвана неправильным действием пользователя — доменное исключение; если ошибка в инфраструктуре — техническое.

"

Добавлено: 23.04.2026