Ответ
Блок finally — это необязательная часть конструкции try-catch в PHP, которая выполняется всегда, независимо от того, было выброшено исключение или нет. Его основное предназначение — код "очистки" (cleanup), который должен быть выполнен в любом сценарии, например, освобождение ресурсов (закрытие файловых дескрипторов, соединений с БД, снятие блокировок).
Ключевое поведение:
$resource = null;
try {
$resource = fopen('data.txt', 'r');
// Чтение данных...
if (someCondition()) {
return 'Early Return'; // finally ВСЁ РАВНО выполнится!
}
// Другие операции, которые могут выбросить исключение...
} catch (IOException $e) {
echo "Ошибка ввода-вывода: {$e->getMessage()}";
throw new RuntimeException('Wrapped', 0, $e); // finally ВСЁ РАВНО выполнится!
} finally {
// Этот код выполнится в ЛЮБОМ случае:
// после успешного завершения try, после catch, даже после return или нового throw.
if ($resource !== null && is_resource($resource)) {
fclose($resource); // Критически важно закрыть ресурс
echo "Файл закрыт.n";
}
}
// Если в finally не было своего return/throw, выполнение продолжится здесь.
Важные нюансы:
- Возврат значения: Если в блоке
finallyесть операторreturn, он переопределит любойreturnиз блоковtryилиcatch.function test() { try { return 'from try'; } finally { return 'from finally'; // Это значение будет возвращено функцией! } } echo test(); // Выведет: 'from finally' - Исключения: Если исключение выброшено в
finally, оно "затенит" любое исключение, выброшенное ранее вtryилиcatch. - Порядок выполнения: Сначала выполняется
try/catch, затемfinally, и только потом происходит возврат значения или проброс исключения (если они были определены вtry/catch).
Ответ 18+ 🔞
А, блядь, finally! Это же та самая штука, которая всех новичков вводит в ступор, пока они не наступят на грабли. Слушай сюда, сейчас разжую.
Представь себе, что ты пошёл в баню. Блок try — это когда ты заходишь в парилку, греешься, можешь даже веником похлестаться. Блок catch — это если ты поскользнулся на мокром полу и ебнулся об полок. А finally — это момент, когда ты, вне зависимости от того, хорошо пропотел или лицом в пол, обязательно идёшь в душ и смываешь с себя всю эту историю. Потому что иначе вонять будешь, как смерд пердящий.
Вот и в коде так же. Ты открыл файл, подключился к базе, залочил мьютекс — это твоя парилка. Всё пошло по плану? Отлично. Всё пошло по пизде и вылетело исключение? Печально, но факт. А finally — это твой гарантированный душ. Закрыть файл, отключиться от базы, снять лок — это надо сделать всегда. Иначе ресурсы повиснут, и сервер твой скоро будет похож на помойку.
Вот смотри на этот пример, он как раз про файл:
$handle = null;
try {
$handle = fopen('секреты_соседа.txt', 'r');
// Читаем, что он там про тебя думает...
if (узнал_что-то_шокирующее()) {
return 'Иду жаловаться в полицию!'; // Ранний возврат! Но finally ВСЁ РАВНО сработает!
}
// ... остальной код, который может бахнуть исключением
} catch (IOException $e) {
echo "Бля, файл не читается: {$e->getMessage()}";
throw new RuntimeException('Заворачиваю ошибку', 0, $e); // Кидаем дальше! Но finally ВСЁ РАВНО сработает!
} finally {
// А вот это — святое. Выполнится при ЛЮБОМ раскладе:
// после try, после catch, после return, даже после нового throw.
if ($handle !== null && is_resource($handle)) {
fclose($handle); // Закрываем, блять, файл! Это главное!
echo "Файл закрыт. Сосед ничего не узнает.n";
}
}
// И только если в finally не было своего return или throw, жизнь пойдёт дальше здесь.
Теперь про две важные, но ебнутые на первый взгляд, особенности. Внимание на хуй!
-
Кто возвращает значение — тот и главный. Если в
finallyвдруг написатьreturn, то он затрет собой любойreturnизtryилиcatch. Это как если бы ты, выходя из душа, решил, что вообще-то ты не из бани, а из космоса вернулся.function кто_здесь_главный() { try { return 'Попытка вернуться из try'; } finally { return 'АХА! Власть захвачена finally!'; // Вернётся именно ЭТО! } } echo кто_здесь_главный(); // Выведет: 'АХА! Власть захвачена finally!'Удивление пиздец, да? Но так работает. Доверия к такому коду — ебать ноль, лучше так не делать.
-
Драка исключений. Если в
finallyвылетает своё исключение, то оно перебивает то, что летело до него изtryилиcatch. Представь: ты поскользнулся (исключение из try), летишь на пол, но в полёте тебя ещё и вентилятором по ебалу бьёт (исключение из finally). В итоге все запомнят только удар вентилятором. Вот эта, блядь, мартышлюшка.
Итог: finally — это твой надёжный уборщик, твой гарант. Используй его для очистки ресурсов. Но помни — если он начнёт сам возвращать значения или кидать исключения, то может устроить такую хитрую жопу, что потом будешь дебажить до посинения. Э сабака сука, аккуратнее с ним.