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

Расскажите об обработке исключений в PHP: try, catch, finally и throw.

1.3 Junior🔥 162 комментариев
#PHP Core#ООП

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

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

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

# Обработка исключений в PHP: try, catch, finally и throw

Обработка исключений — это механизм управления ошибками, который позволяет отделить нормальный поток выполнения программы от обработки аномальных ситуаций. В отличие от традиционной обработки ошибок через функции вроде set_error_handler() или проверку возвращаемых значений, исключения предоставляют более структурированный и объектно-ориентированный подход.

Основные конструкты

1. Блок try — зона риска

Блок try содержит код, в котором могут возникнуть исключения. Если внутри этого блока происходит исключение, выполнение немедленно передается соответствующему блоку catch.

try {
    // Код, который может вызвать исключение
    $file = fopen('несуществующий_файл.txt', 'r');
    $content = fread($file, 1024);
    fclose($file);
} catch (Exception $e) {
    // Обработка исключения
}

2. Оператор throw — инициирование исключения

throw используется для явного создания исключения. В PHP исключения — это объекты классов, унаследованных от базового класса Exception или реализующих интерфейс Throwable.

function divide($numerator, $denominator) {
    if ($denominator == 0) {
        throw new InvalidArgumentException('Деление на ноль запрещено');
    }
    return $numerator / $denominator;
}

3. Блок catch — обработчик исключений

Блок catch перехватывает исключения определенного типа. Можно использовать несколько блоков catch для обработки разных типов исключений.

try {
    divide(10, 0);
} catch (InvalidArgumentException $e) {
    // Обработка исключения типа InvalidArgumentException
    echo 'Ошибка аргумента: ' . $e->getMessage();
} catch (Exception $e) {
    // Обработка всех остальных исключений
    echo 'Общая ошибка: ' . $e->getMessage();
}

4. Блок finally — код завершения

Блок finally выполняется всегда, независимо от того, было выброшено исключение или нет. Это идеальное место для освобождения ресурсов (закрытие файлов, соединений с БД).

$handle = null;
try {
    $handle = fopen('data.txt', 'r');
    // Работа с файлом
} catch (Exception $e) {
    echo 'Ошибка: ' . $e->getMessage();
} finally {
    // Этот код выполнится в любом случае
    if ($handle !== null) {
        fclose($handle);
        echo 'Файл закрыт';
    }
}

Иерархия исключений в PHP

Начиная с PHP 7, все исключения реализуют интерфейс Throwable, который имеет двух основных потомков:

  • Exception — базовый класс для большинства исключений приложения
  • Error — для критических ошибок ядра PHP (с PHP 7)
try {
    // Код, который может вызвать как Exception, так и Error
} catch (DivisionByZeroError $e) {
    // Обработка ошибки деления на ноль (тип Error)
} catch (InvalidArgumentException $e) {
    // Обработка исключения приложения
} catch (Throwable $e) {
    // Перехват всех исключений и ошибок
}

Создание пользовательских исключений

Вы можете создавать собственные классы исключений для более точной классификации ошибок:

class DatabaseConnectionException extends RuntimeException {
    protected $code = 1001;
    
    public function __construct($message = "Ошибка подключения к БД", Throwable $previous = null) {
        parent::__construct($message, $this->code, $previous);
    }
}

class InvalidQueryException extends LogicException {
    protected $code = 1002;
}

// Использование
try {
    if (!$dbConnection) {
        throw new DatabaseConnectionException();
    }
} catch (DatabaseConnectionException $e) {
    // Специфичная обработка ошибки подключения
}

Практические рекомендации

Логирование исключений

Всегда логируйте исключения для последующего анализа:

try {
    // Код приложения
} catch (Exception $e) {
    error_log('[' . date('Y-m-d H:i:s') . '] ' . 
              $e->getMessage() . ' in ' . 
              $e->getFile() . ':' . 
              $e->getLine());
    throw $e; // Прокидываем исключение дальше
}

Цепочка исключений

PHP поддерживает цепочки исключений через параметр $previous:

try {
    // Первичная операция
} catch (Exception $e) {
    throw new CustomException('Дополнительная информация', 0, $e);
}

Глобальный обработчик исключений

Для неперехваченных исключений можно установить глобальный обработчик:

set_exception_handler(function (Throwable $e) {
    echo "Неперехваченное исключение: " . $e->getMessage();
    // Здесь можно выполнить логирование и корректное завершение
});

Лучшие практики

  1. Не скрывайте исключения без веской причины — пустое тело блока catch считается антипаттерном
  2. Используйте конкретные типы исключений в блоках catch вместо общего Exception, когда это возможно
  3. Освобождайте ресурсы в блоке finally или используйте RAII-подобные паттерны
  4. Документируйте исключения в PHPDoc для методов
  5. Рассмотрите использование монад или специальных типов для обработки ошибок в функциональном стиле

Особенности PHP 8.0+

В PHP 8.0+ появились non-capturing catches и возможность указания нескольких типов исключений в одном блоке catch:

try {
    // Код
} catch (InvalidArgumentException|RuntimeException $e) {
    // Обработка двух типов исключений
} catch (Exception) {
    // Исключение перехвачено, но не присвоено переменной
    echo "Произошла ошибка";
}

Правильная обработка исключений делает код более надежным, понятным и упрощает отладку, создавая четкое разделение между нормальной логикой программы и обработкой ошибок.

Расскажите об обработке исключений в PHP: try, catch, finally и throw. | PrepBro