0Pricing
PHP Academy · Урок

Try, Catch и Finally

Корректно обрабатывайте исключения времени выполнения с помощью блоков try/catch/finally

«Try, Catch и Finally» — бесплатный урок PHP Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения PHP Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс PHP Academy содержит 4 уроков всего.

Исключения и ошибки

В PHP есть два способа сообщать о проблемах:

  • Ошибки — традиционные уведомления, предупреждения и критические ошибки PHP (рассматривались на предыдущем уроке)
  • Исключения — объекты, выбрасываемые при возникновении исключительной ситуации; их можно перехватывать с помощью try/catch

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

Выбрасывание исключения

Используйте throw, чтобы сообщить о возникновении проблемы:

<?php
function divide(float $a, float $b): float {
    if ($b == 0) {
        throw new InvalidArgumentException('Cannot divide by zero');
    }
    return $a / $b;
}

echo divide(10, 2);   // 5
// divide(10, 0);     // throws exception

Блок try / catch

Помещайте код, который может выбросить исключение, в try, а обрабатывайте исключения в catch:

<?php
try {
    $result = divide(10, 0);
    echo $result;
} catch (InvalidArgumentException $e) {
    echo 'Error: ' . $e->getMessage();
    echo ' in ' . $e->getFile() . ':' . $e->getLine();
}

Несколько блоков catch

Перехватывайте разные типы исключений в отдельных блоках catch:

<?php
try {
    $pdo = new PDO($dsn, $user, $pass);
    $result = performQuery($pdo);
} catch (PDOException $e) {
    error_log('DB error: ' . $e->getMessage());
    echo 'Database unavailable';
} catch (RuntimeException $e) {
    echo 'Runtime error: ' . $e->getMessage();
} catch (\Throwable $e) {
    echo 'Unexpected error: ' . $e->getMessage();
}

Блок finally

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

<?php
$connection = null;
try {
    $connection = openDatabaseConnection();
    $data = fetchData($connection);
} catch (DatabaseException $e) {
    error_log($e->getMessage());
    echo 'DB error';
} finally {
    // Always runs — even if exception was thrown
    if ($connection) {
        closeConnection($connection);
    }
}

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

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

  • Throwable (интерфейс)
  • ├─ Error — ошибки движка PHP (TypeError, ParseError…)
  • └─ Exception — исключения приложения
  • ├─ RuntimeException
  • ├─ InvalidArgumentException
  • ├─ LogicException
  • └─ PDOException

Перехват Throwable

Перехватывайте и исключения, и ошибки PHP с помощью Throwable:

<?php
try {
    $result = someFunction();
} catch (\Exception $e) {
    echo 'Exception: ' . $e->getMessage();
} catch (\Error $e) {
    echo 'PHP Error: ' . $e->getMessage();
}

// Or catch both at once:
try {
    // ...
} catch (\Throwable $e) {
    echo get_class($e) . ': ' . $e->getMessage();
}

Объединённый catch (PHP 8)

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

<?php
try {
    processRequest();
} catch (InvalidArgumentException | RuntimeException $e) {
    echo 'Handled: ' . $e->getMessage();
}

// Compare PHP 7 approach:
// catch (InvalidArgumentException $e) { ... }
// catch (RuntimeException $e) { ... }

Повторное выбрасывание исключений

Перехватывайте исключение, записывайте его в журнал и выбрасывайте повторно, чтобы передать его вверх по стеку вызовов:

<?php
function processOrder(int $id): void {
    try {
        $order = loadOrder($id);
        $order->process();
    } catch (PaymentException $e) {
        error_log('Payment failed for order ' . $id . ': ' . $e->getMessage());
        throw $e;  // re-throw after logging
    }
}

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

Передавайте исходное исключение как «предыдущее», чтобы сохранить контекст:

<?php
try {
    $data = fetchFromAPI();
} catch (NetworkException $e) {
    throw new ServiceUnavailableException(
        'Cannot reach upstream service',
        0,
        $e  // $previous — preserves original cause
    );
}

// Retrieve original:
// $e->getPrevious()

set_exception_handler

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

<?php
set_exception_handler(function(\Throwable $e): void {
    error_log(sprintf(
        '[UNCAUGHT] %s: %s in %s:%d',
        get_class($e),
        $e->getMessage(),
        $e->getFile(),
        $e->getLine()
    ));
    http_response_code(500);
    echo 'An unexpected error occurred. Please try again.';
    exit(1);
});

Быстрая проверка

Какой блок в конструкции try/catch/finally гарантированно выполнится независимо от того, было ли выброшено исключение?

Итоги: try/catch/finally

Кратко об обработке исключений:

  • Выбрасывайте исключения с помощью throw new ExceptionClass()
  • Перехватывайте их с помощью catch (Type $e)
  • Используйте несколько блоков catch для разных типов
  • finally выполняется всегда — используйте его для очистки ресурсов
  • Объединённый catch в PHP 8: catch (A | B $e)
  • Выбрасывайте исключение повторно, чтобы сохранить контекст стека вызовов

Часто задаваемые вопросы

Урок «Try, Catch и Finally» бесплатный?

Да — полный текст урока «Try, Catch и Finally» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс PHP Academy, подпишись на CoddyKit PRO. Курс PHP Academy содержит 4 уроков всего.

Чему я научусь в уроке «Try, Catch и Finally»?

Корректно обрабатывайте исключения времени выполнения с помощью блоков try/catch/finally Ты практикуешь PHP Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать PHP Academy?

Предыдущий опыт не требуется. PHP Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Try, Catch и Finally»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке PHP Academy?

Да. Каждый урок PHP Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Типы ошибок PHP и их отчётность
  2. Try, Catch и Finally
  3. Создание пользовательских исключений
  4. Журналирование ошибок и лучшие практики
← Назад к PHP Academy