Ответ
Блок 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();
}
Ключевое поведение:
finallyвыполняется всегда — после успешногоtry, послеcatch, даже если вcatchестьreturnилиthrow- Порядок выполнения:
try→ (catchесли есть исключение) →finally→ (возврат/проброс если были в catch) - Если в
finallyесть свойreturn, он переопределит возвращаемое значение изtry/catch
Типичные use cases:
- Закрытие файловых дескрипторов (
fclose()) - Освобождение сокетов и сетевых соединений
- Снятие блокировок (локи файлов, мьютексы)
- Сброс флагов и временных состояний