What is Finally for in PHP 5.5?

Asked

Viewed 869 times

13

PHP 5.5 implemented a feature (which I’ve heard exists in other languages) called finally, in the handling of exceptions (together with the try/catch)

We have the following example:

set_error_handler(function ($errno, $errstr, $errfile, $errline ) {

    throw new ErrorException($errstr, 0, $errno, $errfile, $errline); 

});

try{

    $b = (new stdClass)->non_exists; // gera um erro de propósito

} catch(Exception $e) {

 echo  $e->getMessage(), PHP_EOL; // imprime a mensagem da captura da exceção

} finally {

   echo 'acabou!'; // imprime "acabou" (indepentende de entrar no catch ou não
}

In practice, how could it be useful to use the finally? (because I don’t understand why he runs even when he doesn’t fall in catch)

2 answers

11


Essentially it is to ensure that the flow of that block always runs. Even if an exception occurs in the block started by try, the block of finally will run before exiting the function and start to knock down the function call stack.

In general it is used to terminate allocated resources, for example close a file.

There may arise a doubt as to what is the difference to the catch which is also executed when there is an exception. The difference is that the catch is only executed when there is an exception. The finally is executed with or without exception. The execution flow of the program goes from try to the finally always, be why the try closed normally, either because it generated an exception. The catch is a conditional execution block (by launching an exception), the finally is enforceable.

Remembering that the release of an exception will force the execution of both the catch, how much of finally, but any code that comes after this whole block try-catch-finally nothing will be executed.

Perhaps you give an impression of little use of it because of examples that do nothing useful effectively.

Documentation.

Good generic example:

    $recurso = abrir_recurso();
    try {
        $resultado = use_rercurso($rercurso);
    } finally {
        libere_rercurso($rercurso); //acontecendo ou não uma exceção, o recurso será fechado
    }
    return $resultado;

Actual example taken from that blog:

function addRecord($record, $db) {
    try {
      $db->lock($record->table);
      $db->prepare($record->sql);
      $db->exec($record->params);
    } catch(Exception $e) {
        $db->rollback($record);
        if (!write_log($e->getMessage(), $e->getTraceAsString())) {
            throw new Exception('Unable to write to error log.');
        }
    } finally {
        $db->unlock($record->table);
    }
    return true;
}

I put in the Github for future reference.

The example is bad because it captures Exception and launches again but the general idea is this.

Reading suggestion. It’s not the same language but it works the same way.

  • +1. makes sense. That’s why I had seen an example dealing with a writing of a log, where Finally finishes the file opening

  • "perhaps it gives a bad impression of him because of examples that do nothing useful" reminds me the answer you gave when I asked the Array Dereferencing. The PHP Handbook had to show in a way where it could be used for refactoring (or a simplification, perhaps)

  • 3

    @Wallacemaxters the PHP manual is very bad. And the Portuguese version is awful.

  • in my tests, after the finally, the code was executed normally. That’s what I understood? " but any code that comes after all that Try-catch-Finally block nothing will run" ?

  • 1

    See if the emphasis helps you understand better. In your case nay there has been release of an exception, so the rest of the code will run normally.

  • 1

    @Wallacemaxters Important detail is that the finally is executed at all times. Even if you give one return inside the block catch Return will be executed after the code in finally.

  • "In general it is used to terminate allocated resources, for example close a file."+ 1

Show 2 more comments

4

Try => It is the command block that you want to run

Catch = > This is the command block you run if an error occurs (Exception). You Can Treat Multiple exceptions. Catch will only be executed when an exception occurs.

Finally = > Like catch is the block that runs only when an exception occurs, the block finally will always run, regardless of error. A good use of finally is close connection to the database.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.