9

PHP 5.5 has implemented finally to try-catch. My doubt is: when exactly try-catch-finally that might be more helpful than just I write below try-catch?

Example, difference between:

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

Instead of, just:

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

Can send me some example that is common to this case?

Notes:

  1. I talk about try-catch-finally, and not about try-finally, only;
  2. There are some "features" cool, like you cancel current exception and throw a new-other-exception on finally (I don't tried, I read here). I don't know if it is possible without finally;
  3. Would not be more useful something like notcatch? So I can run a code if try goes without an exception. hehe
FThompson
  • 28,352
  • 13
  • 60
  • 93
David Rodrigues
  • 12,041
  • 16
  • 62
  • 90
  • When something needs to happen regardless of an exception occurring. – Ignacio Vazquez-Abrams Mar 23 '14 at 21:41
  • 1
    The `finally` block will *always* be executed, whereas normal code after the `try-catch` may not be, in the case of returning from a method or similar. This allows you to cleanup anything necessary, such as resource usage. – FThompson Mar 23 '14 at 21:42
  • @Vulcan so if I do `try { return something(); } finally { other(); }`, `other()` will run? And if I do `finally { return other(); }`, what will be returned? It's possible? – David Rodrigues Mar 23 '14 at 21:56
  • @Vulcan About research, I do a lot, on Google and SO, but I found more related to Java, and I like to know over PHP. Java support thread, for instance, and finally seems that works even if thread go out, something like that. I don't know about Java, on really. :) – David Rodrigues Mar 23 '14 at 21:58
  • 1
    @DavidRodrigues The value returned in the `finally` block will be the actual value returned from the function. – FThompson Mar 23 '14 at 22:04
  • http://sandbox.onlinephpfunctions.com/code/adf48d1bef3962571aae186ee8d804fecee7557e – David Rodrigues Mar 24 '14 at 22:18

2 Answers2

8

The code within the finally block is always executed after leaving from either try or catch blocks. Of course you may continue writing code after the try-catch and it will be executed as well. But finally could be useful when you'd like to break out of code execution (such as returning from a function, breaking out of a loop etc.). You can find some examples on this page - http://us2.php.net/exceptions, such as:

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!
  }
}

But yes, you are right; finally is not very popular in everyday use. Certainly not as much as try-catch alone.

gat
  • 2,872
  • 2
  • 18
  • 21
2

You might not catch the exception you're throwing, but you still want to run your finally statement before throwing an error (eg. always close a log file or a DB connection before fatally failing because you didn't catch the exception):

<?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);
}

Which would output:

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)

h2ooooooo
  • 39,111
  • 8
  • 68
  • 102