Для чего используется finally в PHP

«Для чего используется finally в PHP» — вопрос из категории PHP Core, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Блок finally в конструкции try-catch я использую для гарантированного выполнения cleanup-операций независимо от того, как завершился блок try или catch. Это критически важно для предотвращения утечек ресурсов.

Реальный пример работы с транзакциями БД:

$connection = null;
try {
    $connection = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
    $connection->beginTransaction();

    // Бизнес-логика
    $stmt = $connection->prepare("UPDATE accounts SET balance = balance - ? WHERE id = ?");
    $stmt->execute([100, 1]);

    $stmt = $connection->prepare("UPDATE accounts SET balance = balance + ? WHERE id = ?");
    $stmt->execute([100, 2]);

    $connection->commit();

} catch (PDOException $e) {
    // Логируем ошибку
    error_log("Transaction failed: " . $e->getMessage());

    if ($connection) {
        $connection->rollBack();
    }

    throw new ApplicationException("Transfer failed", 0, $e);

} finally {
    // Гарантированно закрываем соединение
    if ($connection) {
        $connection = null;
    }

    // Освобождаем другие ресурсы
    gc_collect_cycles();
}

Ключевое поведение:

  1. finally выполняется всегда — после успешного try, после catch, даже если в catch есть return или throw
  2. Порядок выполнения: try → (catch если есть исключение) → finally → (возврат/проброс если были в catch)
  3. Если в finally есть свой return, он переопределит возвращаемое значение из try/catch

Типичные use cases:

  • Закрытие файловых дескрипторов (fclose())
  • Освобождение сокетов и сетевых соединений
  • Снятие блокировок (локи файлов, мьютексы)
  • Сброс флагов и временных состояний