我没有支持finally
的所需PHP版本,所以我想知道是否:
try {
work();
} catch (Exception $e) {
cleanup();
throw $e;
}
cleanup();
完全与
相同try {
work();
} finally {
cleanup();
}
答案 0 :(得分:5)
finally
块的要点是执行,无论try
块中发生了什么,或者跟随catch
个案例。因此,如果您考虑一下,finally块中的代码可以在成功执行try
块之后执行,也可以在抛出任何异常之后执行。因此,如果您像在解决方案中那样编写它,那么您确实完全模仿了这种情况。如果没有异常,则执行try/catch
结构之后的代码;如果有异常 - 任何异常 - 你也会执行它。
我认为finally
支持可以拯救你的唯一情况是,你的版本本身不能,就是你实际上在早期中止外部执行堆栈。例如,如果此代码在函数内部并且您从try
块内返回,那么finally
仍将执行,但在您的手动实现中它当然不能执行。
因此,如果你确保不早退,那么是的,它应该以同样的方式工作。
没有很多方法可以提前保留一个不抛出异常的函数; return
是最明显的,并且exit
,die
或类似的计划会被另一个程序中止。
答案 1 :(得分:4)
最后代码块总是执行 - 如果有异常,如果没有则。但是如果你捕获一个异常并在catch块之后执行cleanup()
,那么是 - 它基本上是相同的。
答案 2 :(得分:1)
来自PHP docs:
在PHP 5.5及更高版本中,也可以在catch块之后指定finally块。 finally块中的代码将始终在try和catch块之后执行,无论是否抛出异常,并且在正常执行恢复之前。
如果查看这些示例,您会注意到即使捕获到异常,finally
块也将始终执行。但是,当存在异常时,代码将不会恢复,因此finally
块是确保即使存在异常也始终执行某些代码行的好方法。
如果finally
阻止使用catch
功能或类似功能,return
阻止将很重要。否则,将您的清理放在finally
区块或try/catch
以下是文档评论中的相关示例:
只是一个例子,为什么finally块有用(5.5)
<?php
//without catch
function example() {
try {
//do something that throws an exeption
}
finally {
//this code will be executed even when the exception is executed
}
}
function example2() {
try {
//open sql connection check user as example
if(condition) {
return false;
}
}
finally {
//close the sql connection, this will be executed even if the return is called.
}
}
?>
答案 3 :(得分:0)
大多数时候,这两个例子都是等效的:
<?php
function work_success() {
echo 'working' . PHP_EOL;
}
function work_fail() {
echo 'working with fail' . PHP_EOL;
throw new Exception('exception');
}
function cleanup() {
echo 'cleanup' . PHP_EOL;
}
没有finally
的代码:
try {
work();
} catch (Exception $e) {
cleanup();
throw $e;
}
cleanup();
代码finally
:
try {
work();
} finally {
cleanup();
}
work = work_success
和非finally
版本的finally
结果:
working
cleanup
work = work_fail
和非finally
版本的finally
结果:
working
cleanup
Exception: exception
就像@poke所说的那样,将你的例子与控制流机制一起使用可能会得到有趣的结果。以下是使用简单return
语句的说明:
function test()
{
try {
return 'success';
} catch (Exception $e) {
cleanup();
throw $e;
}
cleanup();
}
echo test();
这将只输出success
。除非抛出异常,否则cleanup()
不会被触发。根据先前的示例,与上述示例相对应的等效finally
将如下所示:
function test()
{
try {
return 'success';
} finally {
cleanup();
}
}
echo test();
请注意,无论出现任何异常,此都会执行cleanup()
,因此输出将为:
cleanup
success
对于某些人来说,finally
块中的代码在return
语句之前执行是令人惊讶的。只要你意识到这一点,就应该没有问题。