3

模拟 finally 子句的最佳实践是什么?我意识到这可以被认为与这个问题有关(尽管我不认为它是重复的)。

但是,就我而言,我想处理异常,我想使用由 python 定义的 finally (或任何 PHP 等效项或实践):

finally 子句总是在离开 try 语句之前执行,无论是否发生异常。

在 try-catch 块之后松散地编写代码对我来说似乎是一种丑陋的做法。

4

4 回答 4

8

最终添加到 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结构),否则这可能是您的最佳选择。

于 2013-03-12T19:32:07.450 回答
5

这可能被认为是一个不可回答的问题,但是有一些方法可以构建finally不需要的代码,例如“RAII 模式”(“资源获取是初始化”),其中资源的清理是在析构函数中完成的表示该资源的本地范围变量。

这个想法是,如果异常使您脱离函数范围,您的析构函数将触发,因此您的清理工作按预期进行。如果没有抛出异常,您将到达函数的末尾,并且您的变量将超出范围。

一个快速的谷歌找到了这个简单的代码来做任意回调

于 2013-03-12T19:50:52.453 回答
2

PHP 5.5 及更高版本确实具有finally构造。

从文档:

try {
    echo inverse(5) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
} finally {
    echo "First finally.\n";
}
于 2013-03-12T19:32:47.260 回答
0

如果您仍然坚持维护 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.
    };
}
于 2016-05-30T13:45:15.480 回答