我没有所需的支持finally
的PHP版本,所以我想知道这是否是:
try {
work();
} catch (Exception $e) {
cleanup();
throw $e;
}
cleanup();
与完全相同
try {
work();
} finally {
cleanup();
}
无论在try
块中发生什么,或者在以下catch
情况下,finally
块的要点都是执行。因此,如果仔细想想,finally块中的代码要么在成功执行try
块之后执行,要么在抛出任何异常之后执行。因此,如果你像在解决方案中那样写它,那么你确实准确地模仿了这种情况。如果没有异常,则执行try/catch
结构之后的代码;如果有异常——任何异常——你也要执行它
我认为finally
支持的唯一情况可能会将您从中拯救出来,而您的版本本质上无法做到这一点,那就是您实际上提前中止了外部执行堆栈。例如,如果这个代码在一个函数中,并且您从try
块中返回,那么finally
仍然会被执行,但在您的手动实现中,它当然不能执行。
所以,如果你确保你没有提前离开,那么是的,它也应该以同样的方式工作。
没有多少方法可以提前离开函数而不抛出异常;return
是最明显的,用exit
、die
或类似物中止程序将是另一种。
最后,代码块总是执行——如果有exeption,如果没有。但如果您捕获一个exeption并在捕获块之后执行cleanup()
,那么是的,这基本上是一样的。
来自PHP文档:
在PHP 5.5及更高版本中,还可以在catch块之后指定finally块。finally块中的代码将始终在try-and-catch块之后执行,无论是否引发异常,并且在恢复正常执行之前执行。
如果您查看示例,您会注意到即使捕获到异常,finally
块也将始终执行。然而,当出现异常时,代码将不会恢复,因此finally
块是确保即使出现异常也始终执行某些代码行的好方法。
如果您的catch
块使用return
函数或类似函数,finally
块将很重要。否则,将清理放入finally
块或try/catch
之后没有区别
以下是文档注释中有问题的示例:
只是一个为什么最终块是usefull(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.
}
}
?>
一般来说,是的
大多数情况下,这两个例子的作用相当:
<?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();
}
finally
和非finally
版本的work = work_success
时的结果:
working
cleanup
finally
和非finally
版本的work = work_fail
时的结果:
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
语句之前执行的。只要你意识到这一点,就不会有任何问题。