Artemis | Blog | About & Contact

2021 / 03 / 30 (raw)

PHP: Notes on `finally`

Because PHP has a mix of ambiguous low-level errors and higher-level exceptions in its standard library, and the different mechanisms are not well-documented, I took some notes after trying various cases. This is done in a set_error_handler-free context.

I tested the following cases, even the obvious ones.

Nothing happening

In case a piece of code in a try block runs just fine, the finally block is properly executed.

try {
    $meow = 1 + 2;
} finally {
    echo "FINALLY: MEOW\n";
}

Exception thrown

As before, in case anything resembling a Throwable is raised within a try context, the finally block is properly executed.

try {
    throw new Error('ERROR: MEOW');
} finally {
    echo "FINALLY: MEOW\n";
}

Warning raised

When a method within a try context raises a WARNING of any nature (user or system), the finally block is properly executed.

try {
    trigger_error('MEOW MEOW', E_USER_WARNING);
} finally {
    echo "FINALLY: MEOW\n";
}

Keep in mind that, by default, a WARNING being raised doesn't interrupt the runtime or the currently run block.

try {
    trigger_error('MEOW MEOW', E_USER_WARNING);
    // Will be executed
    $meow = 1 + 2;
} finally {
    echo "FINALLY: MEOW\n";
}

Error raised

When a method within a try context raises an ERROR of any nature (user or system), the finally block is skipped, and the whole runtime stops.

try {
    trigger_error('MEOW MEOW', E_USER_ERROR);
} finally {
    // Will never be reached
    echo "FINALLY: MEOW\n";
}

Assertion raised

When an assertion within a try context fails, the finally block is skipped, and the whole runtime stops.

try {
    assert(false);
} finally {
    // Will never be reached
    echo "FINALLY: MEOW\n";
}

goto used to jump out of the block

As expected of goto, if you use this instruction to jump to an arbitrary location of code outside of the reach of the finally block, it will be skipped.

try {
    goto meow;
} finally {
    // Will never be reached
    echo "FINALLY: MEOW\n";
}
meow:
echo "GOTO: MEOW\n";