devnotes.

Exceptions: try, catch, finally

Instead of relying on error return codes, modern PHP uses exceptions to signal and handle error conditions.

function divide(float $a, float $b): float
{
    if ($b === 0.0) {
        throw new InvalidArgumentException('Cannot divide by zero.');
    }
    return $a / $b;
}

try {
    echo divide(10, 0);
} catch (InvalidArgumentException $e) {
    echo 'Error: ' . $e->getMessage();
} finally {
    echo 'Calculation attempted.'; // always runs, whether an exception occurred or not
}

You can catch multiple exception types in one block using |:

try {
    // risky code
} catch (InvalidArgumentException | TypeError $e) {
    // handle either
}

PHP's built-in exception hierarchy includes Exception and Error (both implement Throwable), with useful subclasses like InvalidArgumentException, RuntimeException, OutOfRangeException, DivisionByZeroError, and TypeError. Since PHP 8.0, unhandled Throwables produce a clear stack trace by default, making debugging much easier than older PHP versions.

Since PHP 8.0, you can also omit the caught variable entirely if you don't need it: catch (RuntimeException) { ... }.

PHP Exceptions: try, catch, finally | DevNotes