Advanced PHP Error Handling and Logging

Error handling is an essential aspect of any PHP application, ensuring that issues are managed gracefully and logged properly for debugging and analysis.

Why Error Handling Matters

Proper error handling helps you:

  • Maintain the stability of your application.
  • Provide user-friendly error messages.
  • Log issues for further investigation.
  • Prevent sensitive information from being exposed to users.

By implementing a robust error handling strategy, you can ensure a better user experience and smoother debugging process.

PHP Error Levels

PHP categorizes errors into different levels, which are important to understand for effective error handling:

  • E_ERROR: Fatal runtime errors that cause script termination.
  • E_WARNING: Non-fatal runtime errors that do not stop script execution.
  • E_NOTICE: Runtime notices indicating possible bugs.
  • E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE: User-generated equivalents of the above levels, triggered using trigger_error().

Understanding these levels helps you decide how to handle different types of errors in your application.

Using try, catch, and finally

PHP’s try, catch, and finally blocks are powerful tools for handling exceptions. Here’s a quick example:

try {
    $db = new PDO('mysql:host=localhost;dbname=testdb', 'username', 'password');
    // Perform database operations
} catch (PDOException $e) {
    // Handle database connection error
    echo 'Connection failed: ' . $e->getMessage();
} finally {
    // Code here always runs, whether or not an exception was thrown
    echo 'Database connection attempt complete.';
}

In this example:

  • try block contains code that may throw an exception.
  • catch block catches and handles the exception.
  • finally block executes code that needs to run regardless of whether an exception occurred.

Using these blocks allows you to isolate error-prone code and handle errors without crashing your entire application.

Creating Custom Error Handlers

For more control over error handling, you can create custom error handlers using set_error_handler() and set_exception_handler():

Example: Custom Error Handler

function customErrorHandler($severity, $message, $file, $line) {
    $logMessage = "[Error] Severity: $severity - Message: $message in $file on line $line";
    error_log($logMessage, 3, __DIR__ . '/logs/errors.log');
    
    // Display a user-friendly message if in production
    if (ini_get('display_errors') == 0) {
        echo "Something went wrong. Please try again later.";
    }
}

set_error_handler('customErrorHandler');

This custom error handler:

  • Logs the error message to a file.
  • Displays a generic message to the user in production environments to avoid exposing sensitive information.

Example: Custom Exception Handler

function customExceptionHandler($exception) {
    $logMessage = "[Exception] " . $exception->getMessage() . " in " . $exception->getFile() . " on line " . $exception->getLine();
    error_log($logMessage, 3, __DIR__ . '/logs/exceptions.log');
    
    echo "An error occurred. Please contact support.";
}

set_exception_handler('customExceptionHandler');

This custom exception handler logs uncaught exceptions and displays a generic error message, keeping the user experience smooth.

Logging Errors with Monolog

While PHP’s built-in error_log() function is useful, you can take logging to the next level with Monolog, a powerful logging library for PHP. Monolog supports various logging handlers like files, databases, and third-party services.

Installing Monolog

To install Monolog using Composer, run:

composer require monolog/monolog

Basic Usage of Monolog

use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$log = new Logger('app');
$log->pushHandler(new StreamHandler(__DIR__ . '/logs/app.log', Logger::WARNING));

// Add records to the log
$log->warning('This is a warning.');
$log->error('This is an error.');

In this example:

  • A new Logger instance is created.
  • The StreamHandler sends log messages to a file.
  • Different log levels, like warning and error, help categorize messages.

Monolog offers many more handlers and integrations, making it suitable for advanced logging needs.

Configuring Error Reporting in Production

In a production environment, you generally don’t want to display errors directly to users. Instead, log errors while keeping the user interface clean. To configure error reporting for production, use the following settings in your php.ini file:

error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT
display_errors = Off
log_errors = On
error_log = /path/to/your/error.log

This setup ensures that:

  • All errors except notices and deprecations are reported.
  • Errors are not displayed to users but are logged to a file.