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

Как работает обработка исключений в PHP?

1.0 Junior🔥 141 комментариев
#PHP Core

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

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

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

Механизм обработки исключений в PHP

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

Базовые конструкции

Основу системы составляет блок try-catch:

try {
    // Код, который может вызвать исключение
    $result = riskyOperation();
    echo $result;
} catch (Exception $e) {
    // Обработка исключения
    echo 'Произошла ошибка: ' . $e->getMessage();
}

Когда в блоке try возникает исключение, выполнение немедленно прерывается, и управление передаётся в соответствующий блок catch.

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

PHP использует объектно-ориентированную систему исключений. Все исключения наследуются от базового класса Exception:

class InvalidArgumentException extends Exception {}
class DatabaseConnectionException extends RuntimeException {}

try {
    if ($value < 0) {
        throw new InvalidArgumentException('Значение не может быть отрицательным');
    }
    
    if (!$this->connect()) {
        throw new DatabaseConnectionException('Не удалось подключиться к БД');
    }
} catch (InvalidArgumentException $e) {
    // Обработка конкретного типа исключения
    echo 'Ошибка аргумента: ' . $e->getMessage();
} catch (RuntimeException $e) {
    // Более общий обработчик
    echo 'Ошибка времени выполнения: ' . $e->getMessage();
} catch (Exception $e) {
    // Универсальный обработчик
    echo 'Неизвестная ошибка: ' . $e->getMessage();
}

Блок finally

Блок finally выполняется всегда, независимо от того, было выброшено исключение или нет:

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

Встроенные классы исключений

PHP предоставляет несколько встроенных классов исключений:

  • Exception - базовый класс для всех исключений
  • ErrorException - исключение для ошибок времени выполнения
  • RuntimeException - исключения, которые могут возникнуть во время выполнения
  • LogicException - исключения, связанные с логическими ошибками в коде

Собственные исключения

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

class PaymentProcessingException extends Exception 
{
    private $transactionId;
    
    public function __construct($message, $transactionId, $code = 0, Throwable $previous = null)
    {
        $this->transactionId = $transactionId;
        parent::__construct($message, $code, $previous);
    }
    
    public function getTransactionId()
    {
        return $this->transactionId;
    }
}

try {
    // Неудачная попытка платежа
    throw new PaymentProcessingException('Недостаточно средств', 'TX123456');
} catch (PaymentProcessingException $e) {
    echo 'Ошибка платежа ' . $e->getTransactionId() . ': ' . $e->getMessage();
    // Можно отправить уведомление, сделать откат транзакции и т.д.
}

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

PHP поддерживает цепочки исключений (exception chaining), что позволяет сохранять оригинальное исключение:

try {
    // Попытка подключения к базе данных
    $this->connectToDatabase();
} catch (PDOException $originalException) {
    // Создаём новое исключение с сохранением оригинального
    throw new ServiceUnavailableException(
        'Сервис временно недоступен',
        503,
        $originalException
    );
}

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

Для обработки исключений, которые не были перехвачены, можно использовать функцию set_exception_handler():

set_exception_handler(function (Throwable $exception) {
    // Логирование исключения
    error_log('Необработанное исключение: ' . $exception->getMessage());
    
    // Пользовательское сообщение
    if (php_sapi_name() === 'cli') {
        echo "Критическая ошибка: " . $exception->getMessage() . PHP_EOL;
    } else {
        http_response_code(500);
        echo 'Извините, произошла внутренняя ошибка сервера';
    }
});

Различия между исключениями и ошибками

Важно понимать разницу:

  • Исключения можно и нужно перехватывать и обрабатывать
  • Ошибки (Fatal, Parse и др.) традиционно не являются исключениями, но начиная с PHP 7 многие ошибки стали выбрасываться как объекты класса Error, который реализует интерфейс Throwable

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

  1. Специфичность обработки - ловите наиболее специфичные исключения первыми
  2. Логирование - всегда логируйте исключения для последующего анализа
  3. Безопасность - не выводите техническую информацию об исключениях пользователям
  4. Чистые ресурсы - используйте finally для освобождения ресурсов
  5. Информативность - добавляйте контекстную информацию в сообщения об исключениях

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