Error Handling in PHP: try/catch and Advanced Techniques

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why Basic Error Handling is Just the Beginning



Every PHP developer knows the try/catch construct. But when a project grows to thousands of lines of code and server load becomes high, simple exception catching is not enough. Advanced error handling is not just "catch and forget," but a whole system: from logging to transforming warnings into exceptions.



In this article, we will cover techniques that will help you write reliable and fault-tolerant code: multiple catch blocks, custom exception classes, global handlers, and integration with PSR-3 loggers. The material is intended for developers already familiar with the basics of PHP.



1. Multiple Catch Blocks and Exception Hierarchy



Starting with PHP 7.1, you can catch different types of exceptions in a single try block. This allows you to respond to errors in a targeted manner:



<?phpclass DatabaseException extends \\Exception {}class ValidationException extends \\Exception {}

try { // code that may throw different exceptions $user = $db->query('SELECT ...'); if (!$user) { throw new DatabaseException('Query error'); } if (empty($user['email'])) { throw new ValidationException('Email is required'); }} catch (DatabaseException $e) { // log the DB error error_log('DB Error: ' . $e->getMessage()); echo 'Temporary server error. Please try again later.';} catch (ValidationException $e) { // show the user a clear message echo 'Error: ' . htmlspecialchars($e->getMessage());} catch (\\Throwable $e) { // catch everything else (including Error) error_log('Critical: ' . $e->getMessage()); echo 'Critical error.';}?>


Why is this important? Each type of exception requires its own response. A DB error — hide details from the user, a validation error — show the form with the field highlighted, a critical error — send a notification to the administrator.



Note the \\Throwable — this is an interface implemented by both Exception and Error (fatal PHP errors). Use it in the last catch block to ensure no error is missed.



2. Custom Exception Classes: Extending Standards



The standard \\Exception class provides basic functionality. But in real projects, it is convenient to create your own exception hierarchies — this simplifies debugging and handling.



Example structure for a web application:



<?phpnamespace App\\Exceptions;

// Base application exceptionclass AppException extends \\RuntimeException{ protected $context = [];

public function __construct(string $message = '', int $code = 0, ?\\Throwable $previous = null, array $context = []) { parent::__construct($message, $code, $previous); $this->context = $context; }

public function getContext(): array { return $this->context; }}

// Exception for HTTP errorsclass HttpException extends AppException{ private int $statusCode;

public function __construct(int $statusCode, string $message = '', array $context = []) { $this->statusCode = $statusCode; parent::__construct($message, $statusCode, null, $context); }

public function getStatusCode(): int { return $this->statusCode; }}

// Usagethrow new HttpException(404, 'Page not found', ['uri' => $_SERVER['REQUEST_URI']]);?>


Advantages:

  • You can pass additional context (request parameters, user ID) — this simplifies logging.
  • Exceptions are grouped by meaning: HttpException, ValidationException, PaymentException.

Blogs

Book Recommendations