【问题标题】:What's the `finally` keyword for in PHP?PHP 中的“finally”关键字是什么?
【发布时间】:2013-06-25 08:50:20
【问题描述】:

考虑这两个例子

<?php
function throw_exception() {
    // Arbitrary code here
    throw new Exception('Hello, Joe!');
}

function some_code() {
    // Arbitrary code here
}

try {
    throw_exception();
} catch (Exception $e) {
    echo $e->getMessage();
}

some_code();

// More arbitrary code
?>

<?php
function throw_exception() {
    // Arbitrary code here
    throw new Exception('Hello, Joe!');
}

function some_code() {
    // Arbitrary code here
}

try {
    throw_exception();
} catch (Exception $e) {
    echo $e->getMessage();
} finally {
    some_code();
}

// More arbitrary code
?>

有什么区别?是否存在第一个示例不会执行some_code() 而第二个示例执行的情况?我完全没有抓住重点吗?

【问题讨论】:

  • Code within the finally block will always be executed after the try and catch blocks, regardless of whether an exception has been thrown, and before normal execution resumes.
  • 我认为这与此线程有关:stackoverflow.com/questions/15031515/…
  • 只是为了保存其他人从 PHP 手册中复制粘贴,我已经阅读了但不明白这两个示例之间的区别,否则我不会问这个问题。
  • 查看 RFC 文档:wiki.php.net/rfc/finally
  • 旁注: finally 块可用于 PHP5.5+

标签: php try-catch-finally finally


【解决方案1】:

如果您捕获 Exception(任何异常),则两个代码示例是等效的。但是如果你只在你的类块中处理一些特定的异常类型并且发生了另一种异常,那么some_code();只有在你有一个finally块的时候才会被执行。

try {
    throw_exception();
} catch (ExceptionTypeA $e) {
    echo $e->getMessage();
}

some_code(); // Will not execute if throw_exception throws an ExceptionTypeB

但是:

try {
    throw_exception();
} catch (ExceptionTypeA $e) {
    echo $e->getMessage();
} finally {
    some_code(); // Will be execute even if throw_exception throws an ExceptionTypeB
}

【讨论】:

  • some_code() 不会被执行时引用一个特定的实例值得+1
  • 我花了一段时间研究它们为什么有用,最后(不是双关语),你的回答为 finally 块的必要性提供了一个有效的理由。
【解决方案2】:

fianlly 块用于当您希望执行一段代码而不管是否发生异常...

查看此页面上的示例 2:

PHP manual

【讨论】:

    【解决方案3】:

    即使没有捕获到异常,最终也会触发。

    试试这个代码看看为什么:

    <?php
    class Exep1 extends Exception {}
    class Exep2 extends Exception {}
    
    try {
      echo 'try ';
      throw new Exep1();
    } catch ( Exep2 $e)
    {
      echo ' catch ';
    } finally {
      echo ' finally ';
    }
    
    echo 'aftermath';
    
    ?>
    

    输出将是

    try  finally 
    Fatal error: Uncaught exception 'Exep1' in /tmp/execpad-70360fffa35e/source-70360fffa35e:7
    Stack trace:
    #0 {main}
      thrown in /tmp/execpad-70360fffa35e/source-70360fffa35e on line 7
    

    这是给你的小提琴。 https://eval.in/933947

    【讨论】:

      【解决方案4】:

      来自the PHP manual

      在 PHP 5.5 及更高版本中,也可以在 catch 块之后或代替 catch 块指定 finally 块。 finally 块中的代码将始终在 trycatch 块之后执行,无论是否抛出异常,并且在正常执行之前简历。

      请参阅this example in the manual,了解其工作原理。

      【讨论】:

        【解决方案5】:

        http://www.youtube.com/watch?v=EWj60p8esD0

        观看时间: 12:30 起

        观看此视频。 语言虽然是JAVA。 但我认为它很好地说明了异常和 finally 关键字的使用。

        【讨论】:

        • 谢谢soden,这解释了我已经知道的,即不管是否有异常它都会运行。但是放在块之后的代码也是如此,不是吗?将其作为区块的一部分有什么特别的优势吗?
        • 取决于您希望从用户那里抽象出多少异常。一般来说,使用 finally 是很少见的。
        猜你喜欢
        • 2013-09-20
        • 2017-05-27
        • 2011-12-10
        • 2019-12-07
        • 1970-01-01
        • 2013-10-14
        • 2013-05-18
        • 2011-10-15
        • 2014-11-29
        相关资源
        最近更新 更多