模拟 finally 子句的最佳实践是什么?我意识到这可以被认为与这个问题有关(尽管我不认为它是重复的)。
但是,就我而言,我想处理异常,我想使用由 python 定义的 finally (或任何 PHP 等效项或实践):
finally 子句总是在离开 try 语句之前执行,无论是否发生异常。
在 try-catch 块之后松散地编写代码对我来说似乎是一种丑陋的做法。
模拟 finally 子句的最佳实践是什么?我意识到这可以被认为与这个问题有关(尽管我不认为它是重复的)。
但是,就我而言,我想处理异常,我想使用由 python 定义的 finally (或任何 PHP 等效项或实践):
finally 子句总是在离开 try 语句之前执行,无论是否发生异常。
在 try-catch 块之后松散地编写代码对我来说似乎是一种丑陋的做法。
在最终添加到 PHP 的 RFC 中,他们建议使用以下解决方法:
<?php
$db = mysqli_connect();
try {
call_some_function($db);
} catch (Exception $e) {
mysqli_close($db);
throw $e;
}
mysql_close($db);
因此,除非您升级到 PHP 5.5(将包含该finally
结构),否则这可能是您的最佳选择。
这可能被认为是一个不可回答的问题,但是有一些方法可以构建finally
不需要的代码,例如“RAII 模式”(“资源获取是初始化”),其中资源的清理是在析构函数中完成的表示该资源的本地范围变量。
这个想法是,如果异常使您脱离函数范围,您的析构函数将触发,因此您的清理工作按预期进行。如果没有抛出异常,您将到达函数的末尾,并且您的变量将超出范围。
一个快速的谷歌找到了这个简单的代码来做任意回调。
PHP 5.5 及更高版本确实具有finally构造。
从文档:
try {
echo inverse(5) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
} finally {
echo "First finally.\n";
}
如果您仍然坚持维护 5.5 之前的遗留代码,并且您不介意每次调用都强制进行假抛出的开销,那么总会有这个肮脏的小技巧。
try {
// do your worst to mess things up.
throw new Exception("finally");
} catch (Exception $e) {
//TODO: after upgrading to 5.5, make this a legit try/catch/finally
if ( ($msg = $e->getMessage()) != "finally"){
// real catch
echo "Exception doing something :" . $msg;
} else {
// quasi finally.
};
}