何时以及为什么“终于”有用?

时间:2014-03-23 21:38:53

标签: php exception-handling try-catch-finally

PHP 5.5已将finally实施为try-catch。我的疑问是:完全try-catch-finally时,可能比我在try-catch下面写的更有帮助吗?

示例,区别:

try { something(); }
catch(Exception $e) { other(); }
finally { another(); }

而不仅仅是:

try { something(); }
catch(Exception $e) { other(); }
another();

可以给我发一些这个案例常见的例子吗?

备注

  1. 我只谈try-catch-finally,而不是try-finally;
  2. 有一些“功能”很酷,就像你取消当前的异常并最终抛出一个新的其他异常(我没试过,I read here)。我不知道没有finally;
  3. 是否可行
  4. notcatch那样有用吗?因此,如果try没有异常,我可以运行代码。和合

2 个答案:

答案 0 :(得分:6)

finally块中的代码始终在从trycatch块中退出后执行。当然,您可以在try-catch之后继续编写代码,并且也将执行。但是当你想要突破代码执行时(例如从函数返回,突破循环等),最终会很有用。您可以在此页面上找到一些示例 - http://us2.php.net/exceptions,例如:

function example() {
  try {
     // open sql connection
     // Do regular work
     // Some error may happen here, raise exception
  }
  catch (Exception $e){
    return 0;
    // But still close sql connection
  }
  finally {
    //close the sql connection
    //this will be executed even if you return early in catch!
  }
}

但是,你是对的; finally在日常使用中不是很受欢迎。当然没有单独尝试捕捉那么多。

答案 1 :(得分:1)

您可能无法捕获正在抛出的异常,但您仍然希望在抛出错误之前运行finally语句(例如,在致命失败之前始终关闭日志文件或数据库连接,因为您没有'抓住异常):

<?php

$fHandle = fopen('log.txt', 'a');

try {
    echo 'Throwing exception..';
    fwrite($fHandle, 'Throwing exception..');

    throw new BadFunctionCallException();
} catch (RangeException $e) {
    // We only want to log RangeExceptions

    echo 'Threw a RangeException: ' . $e->getMessage();
    fwrite($fHandle, 'Threw a RangeException: ' . $e->getMessage());
} finally {
    // Always make sure that we close the file before throwing an exception, even if we don't catch it

    echo 'Reached the finally block';
    fwrite($fHandle, 'Reached the finally block');
    fclose($fHandle);
}

哪个会输出:

Throwing exception..Reached the finally block
Fatal error: Uncaught exception 'BadFunctionCallException' in /tmp/execpad-dc59233db2b0/source-dc59233db2b0:6
Stack trace:
    #0 {main}
    thrown in /tmp/execpad-dc59233db2b0/source-dc59233db2b0 on line 6

DEMO (without the fopen as eval.in doesn't support it)