Press "Enter" to skip to content

PHP的新特性finally

最近, 我提交的关于finally的RFC:Supports finally keyword已经提交到了PHP主干, 今天就给大家介绍一下这个新特性的背景, 和使用方法.
关于这个特性的需求, 最早是在2005年提出来的: FR #32100, 但一直没有人去实现它. 上个月又有人提出来, 我就是抱着试试的态度去实现了一下, 因为有人告诉我, 一直没有实现, 有一个原因是因为很难实现(或许对于一个码农来说, 喜欢挑战难题, 是天性, 呵呵)..
对于现在的PHP来说, 如果我们需要在发生我们当前不能处理的异常的时候, 做一些工作, 那么就会写下类似于这样代码:

function anonymous () {
   try  {
      function_may_throw_exception();
   } catch (Exception $e) {
      clearup();
      throw $e;
   }
   clearup();
}

我们看到, 我们需要显式的写俩便clearup(). 那么finally就可以解决这个问题.
finally并不是PHP的原创, C#, Javascript, Java..等等其他语言都有, PHP的finally和其他的语言相似.
对于finally来说, 一个比较容易让人迷惑的地方就是在finally中return, 因为finally必须保证一定被执行, 所以如果我们在try中return了, finally也会被调用, 那么如果finally也return呢? 到底最后的return的值是那个呢? 在PHP中来说, 如果在finally中return, 那么就会覆盖原有的return值.

<?php
function anonymous() {
    try {
       return 1;
    } finally {
       return 2;
    }
}
var_dump(anonymous());

会得到int(2).
finally结合异常, return, 和try catch finally嵌套的话, 流程确实有点绕, 这也是为什么一直没有被人能实现的一个原因, 不过让我们看看这个finally执行流程图(来自: Finally Getting finally In PHP?), 会对我们理解这个流程会有帮助:

Finally处理流程

在有了finally以后, 文章开头的例子就可以写作:

function anonymous () {
   try  {
      function_may_throw_exception();
   } finally {
      clearup();
   }
}

这样的特性, 对于一些代码洁癖者来说, 会舒服很多 🙂
代码已经提交到了PHP的主干, 不过等大家能用到, 估计最早也得明年了 (伴随PHP5.5).

23 Comments

  1. rookie
    rookie February 18, 2019

    原来这个feature是鸟哥实现的

  2. westdoverpto.org
    westdoverpto.org June 17, 2017

    I visit everyday some blogs and websites to read articles,
    however this website gives feature based writing.

  3. michael
    michael May 13, 2016

    鸟哥你好:
    今天在调试代码的时候发现了finally使用中的一个问题,百思不得其解。希望请教一下您:
    try {
    throw new Exception();
    } catch() {
    var_dump(0);
    } finally {
    var_dump(1);
    new class();
    var_dump(2);
    }
    在上述代码里,如果我try里面没有抛出异常,或者抛出异常了但是finally里new的是本文件里的类,则0,1,2都能打印出来(不抛异常1不打印),也就是按照正常逻辑执行。但是我今天发现如果我抛出异常后,finally里new的class是别的文件里的类就无法执行,只能打印0,1,但2却打印不出来。请问这是为什么?
    我用的是php5.5

  4. crazy
    crazy August 30, 2012

    请问php源码,怎么看啊。我下载了源码,都是不知从何看起。比如,看某个函数的实现等等。有没有相关的介绍。求指点啊。

  5. heihei
    heihei August 22, 2012

    在try和finally都return的情况下:如果在try里面return语句里面做了操作,那么还有效吗?不是是try里面的return就不执行了?

  6. assad
    assad August 17, 2012

    很讨厌PHP面向对象,学java又学不像,搞不好就是东施效颦了。很多鸡肋的东西。

  7. Joseph
    Joseph August 17, 2012

    看完最后一段,是不是意味着明年将发布5.5版本?

  8. jrsjeff
    jrsjeff August 16, 2012

    这个的确很简洁

  9. ayanamist
    ayanamist August 16, 2012

    Dalvik中对finally的处理是很简单粗暴的,把finally块在try和catch中各写一遍,并把里面所有的return置底,保证finally对应代码在return前执行。
    不知道PHP是不是同样处理的……

  10. fc_lamp
    fc_lamp August 16, 2012

    “在PHP中来说, 如果在finally中return, 那么就会覆盖原有的return值.”

  11. Demon
    Demon August 16, 2012

    在一起,在一起

  12. dk
    dk August 16, 2012

    越来越像java了

  13. 雪候鸟
    雪候鸟 August 16, 2012

    @JimLiu thanks 🙂

  14. JimLiu
    JimLiu August 16, 2012

    第二段代码中的catch疑为finally:)

Comments are closed.