Инструкцию throw можно использовать не только непосредственно в try-блоке, но и внутри любой функции, которая оттуда вызывается. При этом производится выход не только из функции, содержащей throw, но также и из всех промежуточных процедур.
<?php ## Инструкция try во вложенных функциях,
echo "Начало программы.<br>";
try {
echo "Начало try-блока.<br>";
outer();
echo "Конец try-блока.<br>";
} catch (Exception $e) {
echo " Исключение: {$e->getMessage()}<br>";
}
echo "Конец программы.<br>";
function outer() {
echo "Вошли в функцию "._METHOD_ ."<br>";
inner();
echo "Вышли из функции ". _METHOD_ ."<br>";
}
function inner() {
echo "Вошли в функцию "._ METHOD_ ."<br>";
throw new Exception("Hello!")
echo "Вышли из функции ". _METHOD_ ."<br>";
}
?>
//Результат работы данного кода:
Начало программы.
Начало try-блока.
Вошли в функцию outer
Вошли в функцию inner
Исключение: Hello!
Конец программы.
Данное поведение инструкции throw называют раскруткой стека вызовов функции, потому что объект-исключение последовательно передается из одной функции в другую, каждый раз приводя к ее завершению — как бы "отматывает" стек.
Инструкция throw заставляет программу немедленно покинуть охватывающий try-блок, даже если при этом будет необходимо выйти из нескольких промежуточных функций (и даже вложенных try-блоков, если они есть). Иногда необходимо написать код, который бы выполнялся при завершении функции в любом случае — независимо от того, как именно был осуществлен выход из блока.
В языках программирования Java и Delphi для реализации кода-финализатора имеется очень удобная конструкция try...finally, призванная гарантировать выполнение некоторых действий в случае возникновения исключения или внезапного завершения функции по return. Однако РНР 5, пока не поддерживает конструкцию try...finally.
Поскольку любой класс-исключение произволен от класса Exception, мы можем написать один-единственный блок-обработчик для всех возможных исключений в программе:
echo "Начало программы.<br>";
try {
eatThis();
} catch (Exception $e) {
echo "Неперехваченное исключение: ". $e;
}
echo "Конец программы.<br>";
Таким образом, если в функции eatThis() возникнет любая исключительная ситуация, и объект-исключение не будет перехвачен внутри самой процедуры, сработает универсальный код восстановления .
Перехват всех исключений при помощи конструкции catch (Exception ...) позволяет нам обезопаситься от неожиданного завершения работы функции (или блока) и гарантировать выполнение некоторого кода в случае возникновения исключения. В этом отношении конструкция очень похожа на инструкцию finally, которой в РНР на данный момент нет.