# RFC: support finally keyword

- Status: Implemented (PHP 5.5)
- Authors: Xinchen Hui laruence@php.net
- Date: 2012/07/24
- Version: 1.0
- Original: https://wiki.php.net/rfc/finally
- Page: https://externals.io/rfc/finally
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

## Votes

### Should the implementation be merged into trunk? (closed)

Yes: 25 · No: 5

Voters: ab (Yes), aharvey (Yes), arpad (Yes), bjori (No), colder (Yes), derick (No), dragoonis (Yes), felipe (Yes), googleguy (Yes), guilhermeblanco (Yes), hytest (Yes), indeyets (Yes), ircmaxell (Yes), irker (Yes), joey (No), jpauli (Yes), kassner (Yes), klaussilveira (Yes), kriscraig (Yes), laruence (Yes), levim (No), nikic (No), pajoye (Yes), rasmus (Yes), sascham78 (Yes), shm (Yes), stas (Yes), tyrael (Yes), willfitch (Yes), zhangzhenyu (Yes)

## Discussions on the mailing list

- [\[RFC\] Supports 'finally' keyword for PHP exceptions](https://externals.io/message/61670.md) — started on 2012-07-24, 35 messages
- [\[Voting\] Call for voting for RFC: Supports finally keyword](https://externals.io/message/62064.md) — started on 2012-08-06, 2 messages

---

## Introduction

This RFC is try to introduce 'finally' support for exceptions. which is requested from FR #32100, #36779

without this feature, user have to write codes like following one to do cleanup while an un-handlable exception occurred:

```php
<?php
$db = mysqli_connect();
try {
   call_some_function($db);
} catch (Exception $e) {
   mysqli_close($db);
   throw $e;
}
mysql_close($db);
```

introducing finally is not about save one or two lines for such situation, it's about give the user a more proper way to handle such issue.

## Proposal

The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs. But finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated.

```php
<?php
$db = mysqli_connect();
try {
   call_some_function($db);//the function may throw exceptions which we can not handle
} finally {
   mysqli_close($db);
}
```

the most confuse part is call “return in try/catch block”, in this case the finally block will still be called

```php
<?php
  try {
    return 2;
  } finally {
    echo "this will be called\n";
  }
  //this will never be called
  echo "you can not see me";
```

the above script will output:

```
this will be called
//return int(2)
```

and for nesting try catch finally:

```php
<?php
function foo ($a) {
   try {
      echo "1";
      try {
        echo "2";
        throw new Exception("ex");
      } catch (Exception $e) {
        echo "3";
      } finally {
        echo "4";
        throw new Exception("ex");
      } 
   } catch (Exception $e) {
      echo "3";
   } finally {
      echo "2";
   }
   return 1;
}
 
var_dump(foo("para"));
```

will output:

```
123432int(1)
```

There are also lots of edge cases could be found in the Test&amp;Examples section blow

## Patch

- Patch: <https://github.com/laruence/php-src/tree/finally>

## Tests &amp; Examples

- [https://github.com/laruence/php-src/blob/finally/Zend/tests/catch\_finally\_001.phpt](https://github.com/laruence/php-src/blob/finally/Zend/tests/catch_finally_001.phpt)
- [https://github.com/laruence/php-src/blob/finally/Zend/tests/catch\_finally\_002.phpt](https://github.com/laruence/php-src/blob/finally/Zend/tests/catch_finally_002.phpt)
- [https://github.com/laruence/php-src/blob/finally/Zend/tests/catch\_finally\_003.phpt](https://github.com/laruence/php-src/blob/finally/Zend/tests/catch_finally_003.phpt)
- [https://github.com/laruence/php-src/blob/finally/Zend/tests/catch\_finally\_004.phpt](https://github.com/laruence/php-src/blob/finally/Zend/tests/catch_finally_004.phpt)
- [https://github.com/laruence/php-src/blob/finally/Zend/tests/catch\_finally\_005.phpt](https://github.com/laruence/php-src/blob/finally/Zend/tests/catch_finally_005.phpt)
- [https://github.com/laruence/php-src/blob/finally/Zend/tests/catch\_finally\_006.phpt](https://github.com/laruence/php-src/blob/finally/Zend/tests/catch_finally_006.phpt)
- [https://github.com/laruence/php-src/blob/finally/Zend/tests/try\_finally\_001.phpt](https://github.com/laruence/php-src/blob/finally/Zend/tests/try_finally_001.phpt)
- [https://github.com/laruence/php-src/blob/finally/Zend/tests/try\_finally\_002.phpt](https://github.com/laruence/php-src/blob/finally/Zend/tests/try_finally_002.phpt)
- [https://github.com/laruence/php-src/blob/finally/Zend/tests/try\_finally\_003.phpt](https://github.com/laruence/php-src/blob/finally/Zend/tests/try_finally_003.phpt)

## Vote

**Vote: Should the implementation be merged into trunk?** — Yes: 25 · No: 5 (closed)

## Changelog

- 2012/07/24 Xinchen Hui: Initial version
- 2012/07/26 Xinchen Hui: Update RFC
- 2012/08/06 Xinchen Hui: Open voting
- 2012/08/13 Xinchen Hui: Close voting, RFC win the voting
- 2012/08/15 Xinchen Hui: Committed
