PHP Exceptions
Handling errors gracefully with try-catch blocks
⚠️ What are Exceptions?
Exceptions are special objects that represent errors or unexpected conditions in your code. They allow you to handle errors gracefully using try-catch blocks instead of letting your application crash unexpectedly.
<?php
try {
// Code that might throw an exception
$result = 10 / 0;
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
// Output: Error: Division by zero
?>
Output:
Error: Division by zero
Exception Handling Concepts
Try Block
Contains code that might throw an exception. Execution stops at the first exception thrown.
<?php
try {
// Risky code here
$file = fopen("data.txt", "r");
}
?>
Catch Block
Handles exceptions thrown in the try block. You can catch specific exception types.
<?php
catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
?>
Finally Block
Executes regardless of whether an exception was thrown, perfect for cleanup operations.
<?php
finally {
// Always runs
echo "Cleanup complete";
}
?>
Throw Statement
Manually throw exceptions when you detect error conditions in your code.
<?php
if ($age < 18) {
throw new Exception("Too young");
}
?>
🔹 Basic Try-Catch
Catch and handle exceptions to prevent application crashes:
<?php
function divide($a, $b) {
if ($b == 0) {
throw new Exception("Cannot divide by zero!");
}
return $a / $b;
}
try {
echo "10 / 2 = " . divide(10, 2) . "<br>";
echo "10 / 0 = " . divide(10, 0) . "<br>";
echo "This won't execute";
} catch (Exception $e) {
echo "Caught exception: " . $e->getMessage();
}
?>
Output:
10 / 2 = 5
Caught exception: Cannot divide by zero!
🔹 Multiple Catch Blocks
Handle different exception types with separate catch blocks:
<?php
class InvalidAgeException extends Exception {}
class InvalidEmailException extends Exception {}
function validateUser($age, $email) {
if ($age < 18) {
throw new InvalidAgeException("Age must be 18 or older");
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidEmailException("Invalid email format");
}
return "User is valid";
}
try {
echo validateUser(15, "[email protected]");
} catch (InvalidAgeException $e) {
echo "Age Error: " . $e->getMessage();
} catch (InvalidEmailException $e) {
echo "Email Error: " . $e->getMessage();
} catch (Exception $e) {
echo "General Error: " . $e->getMessage();
}
?>
Output:
Age Error: Age must be 18 or older
🔹 Finally Block
Code in finally always executes, even if an exception occurs:
<?php
function processFile($filename) {
$file = null;
try {
echo "Opening file...<br>";
$file = fopen($filename, "r");
if (!$file) {
throw new Exception("File not found");
}
echo "Processing file...<br>";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "<br>";
} finally {
echo "Cleanup: Closing resources<br>";
if ($file) {
fclose($file);
}
}
}
processFile("nonexistent.txt");
?>
Output:
Opening file...
Error: File not found
Cleanup: Closing resources
🔹 Custom Exception Classes
Create your own exception types for specific error scenarios:
<?php
class DatabaseException extends Exception {
public function errorMessage() {
return "Database Error on line {$this->getLine()}: {$this->getMessage()}";
}
}
class ValidationException extends Exception {
private $field;
public function __construct($message, $field) {
parent::__construct($message);
$this->field = $field;
}
public function getField() {
return $this->field;
}
}
try {
throw new ValidationException("Invalid input", "email");
} catch (ValidationException $e) {
echo "Field '{$e->getField()}': {$e->getMessage()}";
}
?>
Output:
Field 'email': Invalid input
🔹 Exception Methods
Access useful information from exception objects:
<?php
try {
throw new Exception("Something went wrong", 500);
} catch (Exception $e) {
echo "Message: " . $e->getMessage() . "<br>";
echo "Code: " . $e->getCode() . "<br>";
echo "File: " . $e->getFile() . "<br>";
echo "Line: " . $e->getLine() . "<br>";
echo "Trace: " . $e->getTraceAsString();
}
?>
Output:
Message: Something went wrong
Code: 500
File: /path/to/file.php
Line: 3
Trace: #0 {main}
🔹 Re-throwing Exceptions
Catch an exception, do something, then throw it again:
<?php
function processData($data) {
try {
if (empty($data)) {
throw new Exception("Data is empty");
}
// Process data...
} catch (Exception $e) {
// Log the error
error_log($e->getMessage());
// Re-throw for higher level handling
throw $e;
}
}
try {
processData("");
} catch (Exception $e) {
echo "Final handler: " . $e->getMessage();
}
?>
Output:
Final handler: Data is empty
🔹 Global Exception Handler
Set a default handler for uncaught exceptions:
<?php
// Set global exception handler
set_exception_handler(function($exception) {
echo "Uncaught Exception: " . $exception->getMessage() . "<br>";
echo "Please contact support.";
});
// This exception won't be caught
throw new Exception("Critical error occurred");
// Code after exception won't execute
echo "This won't display";
?>
Output:
Uncaught Exception: Critical error occurred
Please contact support.
🔹 Best Practices
Exception Handling Tips:
- Be Specific - Catch specific exception types before general ones
- Don't Catch Everything - Only catch exceptions you can handle
- Use Finally - Clean up resources in finally blocks
- Meaningful Messages - Provide clear error messages
- Log Errors - Always log exceptions for debugging
- Custom Exceptions - Create custom exception classes for your domain
- Don't Hide Errors - Don't use empty catch blocks
Common Exception Types:
- Exception - Base exception class
- InvalidArgumentException - Invalid function arguments
- RuntimeException - Errors during runtime
- LogicException - Logic errors in code
- PDOException - Database errors