Programster's Blog

Tutorials focusing on Linux, programming, and open-source

PHP - Finally Clause

PHP

Since 5.5, PHP has supported the finally clause. Finally gets executed after a try block no matter what. E.g. if the try block threw an exception or not.

If you don't have time to step through the examples, just scroll down to the conclusion at the bottom to find out where the finally clause is useful.

The example code below helps with showing this:

<?php

try 
{
    print "Executing try block BEFORE exception thrown." . PHP_EOL;
    throw new Exception("This is my exception");
    print "Executing try block AFTER exception thrown." . PHP_EOL;
} 
catch (Exception $e) 
{
    print "Executing the catch block." . PHP_EOL;
} 
finally 
{
    print "Executing 'finally' block." . PHP_EOL;
}

print "Executing code after finally." . PHP_EOL;

The script will output:

Executing try block BEFORE exception thrown.
Executing the catch block.
Executing 'finally' block.
Executing code after finally.

As you can see, the finally block got executed, but so did the final statement which is outside all of the blocks, so what is the point?

Here is another example:

<?php

try 
{
    print "Executing try block BEFORE exception thrown." . PHP_EOL;
    throw new Exception("This is my exception");
    print "Executing try block AFTER exception thrown." . PHP_EOL;
} 
finally 
{
    print "Executing 'finally' block." . PHP_EOL;
}

print "Executing code after finally." . PHP_EOL;

This will cause the following output:

Executing try block BEFORE exception thrown.
Executing 'finally' block.
PHP Fatal error:  Uncaught Exception: This is my exception in /home/stuart/test.php:7
Stack trace:
#0 {main}
  thrown in /home/stuart/test.php on line 7

As you can see, the code after the finally block never got executed because we had an uncaught exception. This is because the exception still gets raised and is not "caught" by the finally block. However, the finally block still gets executed.

Now you may be asking, well what's the point in the finally block if I have a generic catch statement that catches all exceptions? Well the finally block will still execute if anything within your catch block accidentally or deliberately throws an exception as shown here:

<?php

function doSomeExceptionHandling()
{
    // pretend like this makes a bunch of calls an the stack is very deep
    // e.g. you don't really see the Exception being thrown at this level.
    throw new Exception("Something within my exception handling threw an exception!");
}

try 
{
    print "Executing try block BEFORE exception thrown." . PHP_EOL;
    throw new Exception("This is my exception");
    print "Executing try block AFTER exception thrown." . PHP_EOL;
} 
catch(Exception $e)
{
    doSomeExceptionHandling();
}
finally 
{
    print "Executing 'finally' block." . PHP_EOL;
}

print "Executing code after finally." . PHP_EOL;

This outputs:

Executing try block BEFORE exception thrown.
Executing 'finally' block.
PHP Fatal error:  Uncaught Exception: Something within my exception handling threw an exception! in /home/stuart/test.php:7
Stack trace:
#0 /home/stuart/test.php(18): doSomeExceptionHandling()
#1 {main}
  thrown in /home/stuart/test.php on line 7

As you can see the finally block is still executed, even though something went wrong within our exception handling.

Conclusion

The finally block can be extremely useful if:

  1. There is a risk something within your catch block could possibly throw an exception, and you must run some cleanup code afterwards no matter what.
  2. You don't want to catch the exception (no catch clause).
    • In such a situation, I would personally put in the catch clause and re-throw the exception.

References

Last updated: 26th February 2022
First published: 16th August 2018

This blog is created by Stuart Page

I'm a freelance web developer and technology consultant based in Surrey, UK, with over 10 years experience in web development, DevOps, Linux Administration, and IT solutions.

Need support with your infrastructure or web services?

Get in touch