PHP Exceptions and Error Handling
PHP exceptions are the modern way to handle errors. Instead of returning false and hoping someone checks it, code throws an exception, and the caller decides how to handle it with try and catch.
Try, Catch and Finally
Code after the throw does not run. finally always runs, which is useful for cleanup.
<?php
function divide(int $a, int $b): float {
if ($b === 0) {
throw new InvalidArgumentException('Cannot divide by zero');
}
return $a / $b;
}
try {
echo divide(10, 2), "\n";
echo divide(1, 0), "\n";
} catch (InvalidArgumentException $e) {
echo "Error: " . $e->getMessage() . "\n";
} finally {
echo "Done";
}5 Error: Cannot divide by zero Done
Catching Several Exception Types
You can catch multiple types with |. Throwable catches both exceptions and engine errors such as TypeError.
<?php
declare(strict_types=1);
function square(int $n): int { return $n * $n; }
try {
echo square("5");
} catch (TypeError | ValueError $e) {
echo get_class($e) . " caught";
}TypeError caught
Custom Exception Classes
Create your own exceptions to describe domain problems clearly. Extend Exception or a more specific SPL class.
<?php
class InsufficientFundsException extends RuntimeException {
public function __construct(public readonly float $shortBy) {
parent::__construct("Short by $shortBy");
}
}
function withdraw(float $balance, float $amount): float {
if ($amount > $balance) {
throw new InsufficientFundsException($amount - $balance);
}
return $balance - $amount;
}
try {
withdraw(50, 80);
} catch (InsufficientFundsException $e) {
echo $e->getMessage() . " (" . $e->shortBy . ")";
}Short by 30 (30)
Error Reporting Settings
- Development: display_errors=On and error_reporting=E_ALL so you see every problem
- Production: display_errors=Off and log_errors=On so users never see stack traces
- set_exception_handler() lets you log any uncaught exception and show a friendly page
- Frameworks like Laravel configure all of this for you
Frequently asked questions
What is the difference between Exception and Error in PHP?
Both implement Throwable. Exception is for problems your code throws; Error is thrown by the engine for things like type errors or calling undefined functions.
Should I catch every exception?
No. Catch exceptions only where you can handle them meaningfully. Let others bubble up to a global handler that logs them.
Does finally run after return?
Yes. A finally block runs even if the try or catch block returns, which makes it reliable for cleanup.