How is the keyword ‘finally’ meant to be used in PHP?

finally executes every* time

Regardless of errors, exceptions, or even return statements, the finally block of code will run.

*It will not run if the try or catch blocks execute die/exit.

Exception

One example is closing a database connection in a process that might otherwise leave a dangling connection that blocks the database server from accepting new connections.

Consider this pseudo-code:

try {
   $database->execute($sql);
} finally {
   $database->close();
}

Here we will always close the database connection. If it’s a normal query, we close connection after success, and the script will continue to execute.

If it’s an erroneous query, then we still close after the exception has been thrown, and the uncaught exception will bubble up.

Here’s an example with catch doing some logging.

try {
   $database->execute($sql);
} catch (Exception $exception) {
   $logger->error($exception->getMessage(), ['sql' => $sql]);
   throw $exception;
} finally {
   $database->close();
}

This will make it close the connection with or without an exception.

Return

One of the more obscure behaviors is its ability to execute code after a return statement.

Here you can set a variable after the function has returned:

function foo(&$x)
{
    try {
        $x = 'trying';
        return $x;
    } finally {
        $x = 'finally';
    }
}

$bar="main";
echo foo($bar) . $bar;

tryingfinally

but an assignment will be what’s returned in try:

$bar = foo($bar);
echo $bar . $bar;

tryingtrying

and returning in the finally overrides the return in the try:

function baz()
{
    try {
        return 'trying';
    } finally {
        return 'finally';
    }
}

echo baz();

finally

note this behavior was different in php 5:

finallyfinally
finallyfinally
finally

https://3v4l.org/biO4e

Exceptional Return

You can kinda make it look like throwing 2 exceptions to bubble up at the same time:

try {
    throw new Exception('try');
} finally {
    throw new Exception('finally');
}
Fatal error: Uncaught Exception: try in /in/2AYmF:4
Stack trace:
#0 {main}

Next Exception: finally in /in/2AYmF:6
Stack trace:
#0 {main}
  thrown in /in/2AYmF on line 6

Process exited with code 255.

https://3v4l.org/2AYmF

But you can’t really catch the “first” exception that I’m aware of to do anything fun at runtime:

try {
    try {
        throw new Exception('try');
    } finally {
        throw new Exception('finally');
    }
} catch (Exception $exception) {
    echo 'caught ' . $exception->getMessage();
}

caught finally

https://3v4l.org/Jknpm

* Die

If you exit or die then the finally block will not execute.

try {
    echo "trying";
    die;
} finally {
    echo "finally";
}

echo "end";

trying

https://3v4l.org/pc9oc

† Hardware Failure

Finally, you should understand that the finally block will not execute if someone pulls the power plug on your server 😉 and although I haven’t tested it, I’d expect memory exhaustion to skip it too.

Leave a Comment

deneme bonusu veren sitelerbahis casinomakrobetceltabetpinbahispolobetpolobet girişpinbahis girişmakrobet girişpulibet girişmobilbahis girişkolaybet giriş