← Назад к вопросам

Какая конструкция обрабатывает Exceptions?

1.6 Junior🔥 192 комментариев
#PHP Core

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Обработка исключений (Exceptions) в PHP

В PHP для обработки исключений используется конструкция try-catch-finally. Это основная и единственная встроенная конструкция языка, предназначенная для отлова и обработки исключительных ситуаций, представленных объектами классов, унаследованных от базового класса Throwable (а точнее, от его потомка Exception).

Основная структура конструкции

<?php
try {
    // Код, который может выбросить исключение
    $result = riskyOperation();
    echo $result;
} catch (SpecificException $e) {
    // Обработка конкретного типа исключения
    echo "Произошла ошибка: " . $e->getMessage();
    // Логирование, восстановление и т.д.
} catch (AnotherException $e) {
    // Обработка другого типа исключения
    echo "Другая ошибка: " . $e->getMessage();
} catch (Exception $e) {
    // "Ловушка" для всех остальных исключений типа Exception
    echo "Неизвестная ошибка: " . $e->getMessage();
} finally {
    // Код, который выполнится ВСЕГДА, независимо от того, было исключение или нет
    cleanupResources();
}
?>

Ключевые компоненты

  1. Блок try:

    • Содержит код, выполнение которого может привести к исключительной ситуации.
    • При возникновении исключения внутри try, выполнение немедленно прерывается и управление передаётся в соответствующий блок catch.
  2. Блоки catch:

    • Определяют обработчики для конкретных типов исключений.
    • Можно указывать несколько блоков catch — они проверяются последовательно сверху вниз, поэтому более специфичные исключения должны обрабатываться раньше общих.
    • Каждый блок catch принимает объект исключения, от которого можно получить информацию:
     * `$e->getMessage()` — сообщение об ошибке.
     * `$e->getCode()` — код ошибки.
     * `$e->getFile()` и `$e->getLine()` — место возникновения.
     * `$e->getTrace()` и `$e->getTraceAsString()` — стек вызовов.

  1. Блок finally (опциональный)**:
    • Выполняется всегда — и при успешном выполнении try, и при перехвате исключения в catch, и даже если исключение не было перехвачено (хотя в последнем случае выполнение прервется после finally).
    • Используется для обязательных операций: закрытия файлов, освобождения ресурсов, сброса флагов и т.д.

Важные особенности и best practices

  • Иерархия исключений: В PHP 7+ все исключения реализуют интерфейс Throwable. Есть два основных типа:

    • Exception — для большинства исключений приложения.
    • Error — для критических ошибок движка (например, фатальные ошибки приведения типов или нехватки памяти). Error также можно перехватывать через catch.
  • Пример с несколькими типами исключений:

<?php
try {
    $pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
    // Может выбросить PDOException
    $stmt = $pdo->query("SELECT * FROM non_existent_table");
} catch (PDOException $e) {
    // Ловим исключения, связанные с БД
    logError($e);
    throw new DatabaseException("Query failed", 0, $e);
} catch (Throwable $e) {
    // Ловим ВСЁ, что может быть выброшено (PHP 7+)
    logCriticalError($e);
    throw $e; // Пробрасываем дальше
}
?>
  • Проброс исключений: Внутри catch можно повторно выбросить то же или новое исключение с помощью throw. Это полезно для:

    • Логирования на низком уровне.
    • Преобразования исключений низкого уровня в исключения уровня приложения.
    • Частичного восстановления и повторной попытки.
  • Глобальный обработчик: Для неперехваченных исключений можно задать глобальный обработчик через set_exception_handler():

<?php
set_exception_handler(function (Throwable $e) {
    error_log("Uncaught exception: " . $e->getMessage());
    http_response_code(500);
    echo "Internal Server Error";
});
?>

Эволюция обработки исключений в PHP

  • До PHP 7: Не было типа Throwable, Error нельзя было перехватывать через catch.
  • PHP 7+: Введён Throwable, что позволило единообразно обрабатывать и Exception, и Error.
  • PHP 8.0+: Появились выражения throw (throw expressions), позволяющие использовать throw в контекстах, где ожидается выражение (например, в тернарных операторах или стрелочных функциях):
<?php
// Пример throw expression в PHP 8+
$value = $input ?? throw new InvalidArgumentException("Input is required");
?>

Заключение

Конструкция try-catch-finally — это краеугольный камень современной обработки ошибок в PHP, позволяющий переходить от процедурного стиля с проверкой кодов возврата к объектно-ориентированному управлению исключительными ситуациями. Её правильное использование повышает надежность, читаемость и поддерживаемость кода, позволяя четко разделять нормальную логику программы и обработку ошибок.