PHP Error Handling

Things go wrong: a file is missing, a division is invalid, an API times out. PHP gives you try/catch/finally to handle these situations gracefully instead of letting the whole script crash with a raw error message.

1) try / catch / finally

Code that might fail goes in try. If it throws, execution jumps to the matching catch. The finally block always runs afterward, whether or not an exception was thrown — useful for cleanup like closing a file or a database connection.

<?php
  try {
    $result = riskyOperation();
  } catch (Exception $e) {
    echo 'Something went wrong: ' . $e->getMessage();
  } finally {
    // runs no matter what
    closeConnection();
  }
?>

2) Throwing Exceptions

Use throw new Exception('message') to signal that something went wrong in a way the caller can catch and react to.

<?php
  function withdraw(float $balance, float $amount): float {
    if ($amount > $balance) {
      throw new Exception('Insufficient funds.');
    }
    return $balance - $amount;
  }
?>

3) Custom Exception Classes

Extend the built-in Exception class to create a specific, catchable type — useful when different failure kinds need different handling.

<?php
  class InvalidAgeException extends Exception {}

  function setAge(int $age): void {
    if ($age < 0 || $age > 150) {
      throw new InvalidAgeException("Age {$age} is not valid.");
    }
  }
?>

This page defines a similar custom exception, DivisionByZeroDemoException, used in the live demo below.

4) Live Demo: A Custom Exception in try/catch

<?php
  class DivisionByZeroDemoException extends Exception {}

  function safeDivide(float $a, float $b): float {
    if ($b === 0.0) {
      throw new DivisionByZeroDemoException("Cannot divide {$a} by zero.");
    }
    return $a / $b;
  }
?>
Calltry/catch outcome (real, live)
safeDivide(10, 2) — valid
Result: 5 (no exception thrown)
safeDivide(10, 0) — deliberately invalid
Caught exception message: Cannot divide 10 by zero.
Both calls really executed on this page load; the second one really threw DivisionByZeroDemoException, which was really caught above instead of crashing the page.

5) Errors vs Exceptions

ErrorsExceptions
Typical causeCalling an undefined function, type errors, out of memoryApplication-level failures you anticipate (bad input, failed lookup)
Can you catch it?Some (via Error class in PHP 7+), but often fatalYes, always — that's their purpose
Typical useIndicates a bug in the codeIndicates an expected-but-exceptional situation to recover from

6) error_reporting() and display_errors: Dev vs Production

In development you want to see every notice and warning. In production you must never show raw errors to visitors (they can leak file paths, queries, or secrets) — log them to a file instead.

<?php
  // Development (php.ini or top of a dev bootstrap file)
  error_reporting(E_ALL);
  ini_set('display_errors', '1');

  // Production
  ini_set('display_errors', '0');
  ini_set('log_errors', '1');
  ini_set('error_log', '/var/log/php/app-errors.log');
?>
Rule of thumb: catch exceptions you can meaningfully recover from, always clean up in finally, create custom exception classes for distinct failure types, and keep display_errors off in production — log instead.