Enable Error Handling in PHP

To enable all errors in PHP and catch fatal errors, you need to configure error reporting and use a combination of error handling techniques. Fatal errors (like E_ERROR) are tricky because they typically halt script execution, but you can catch some of them using a custom error handler or shutdown function. Below is a comprehensive guide with examples.


1. Enable All Errors in PHP

To display and log all errors, including notices, warnings, and fatal errors, configure PHP settings either globally (in php.ini) or at runtime.

Option 1: Configure php.ini

Edit the php.ini file (location depends on your server setup, e.g., /etc/php/8.1/apache2/php.ini on Ubuntu):

display_errors = On
display_startup_errors = On
error_reporting = E_ALL
log_errors = On
error_log = /path/to/error.log

Restart your web server (e.g., Apache or Nginx) after making changes:

sudo service apache2 restart

Option 2: Enable Errors at Runtime

Add the following at the top of your PHP script:

<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

This ensures all errors, including E_NOTICE, E_WARNING, E_ERROR, etc., are reported.


2. Catching Fatal Errors

Fatal errors (e.g., calling a nonexistent function or class) terminate the script, so they can't be caught with a standard try-catch block. However, you can use a shutdown function to handle them.

Steps to Catch Fatal Errors

  1. Set a custom error handler to catch non-fatal errors.
  2. Register a shutdown function to catch fatal errors.
  3. Check for errors in the shutdown function using error_get_last().

Example: Catching All Errors, Including Fatal Errors

Here’s a complete example that enables error reporting, catches non-fatal errors with a custom handler, and catches fatal errors with a shutdown function.

<?php
// Enable all error reporting
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

// Custom error handler for non-fatal errors
function customErrorHandler($errno, $errstr, $errfile, $errline) {
    $errorType = &#91;
        E_ERROR => 'Fatal Error',
        E_WARNING => 'Warning',
        E_NOTICE => 'Notice',
        E_PARSE => 'Parse Error',
        E_CORE_ERROR => 'Core Error',
        E_USER_ERROR => 'User Error',
        E_USER_WARNING => 'User Warning',
        E_USER_NOTICE => 'User Notice',
        // Add other error types as needed
    ];

    $type = isset($errorType[$errno]) ? $errorType[$errno] : 'Unknown Error';
    $message = "[$type] $errstr in $errfile on line $errline\n";

    // Log to file or display
    error_log($message, 3, 'error.log');
    echo $message;

    // Return false to let PHP handle the error normally
    return false;
}

// Set the custom error handler
set_error_handler('customErrorHandler');

// Register shutdown function to catch fatal errors
register_shutdown_function(function () {
    $error = error_get_last();
    if ($error !== null) {
        $errno = $error['type'];
        $errstr = $error['message'];
        $errfile = $error['file'];
        $errline = $error['line'];

        $message = "[Shutdown Error] Type: $errno, Message: $errstr in $errfile on line $errline\n";

        // Log to file or display
        error_log($message, 3, 'error.log');
        echo $message;
    }
});

// Example: Trigger a non-fatal error (Notice)
echo $undefinedVariable;

// Example: Trigger a fatal error
nonExistentFunction();

?>

Explanation of the Code

  1. Error Reporting: error_reporting(E_ALL) and ini_set('display_errors', 1) ensure all errors are reported and displayed.
  2. Custom Error Handler: customErrorHandler catches non-fatal errors (e.g., E_NOTICE, E_WARNING) and logs them to error.log while also displaying them.
  3. Shutdown Function: register_shutdown_function runs after the script ends, even if a fatal error occurs. It uses error_get_last() to check for fatal errors and logs/displays them.
  4. Error Triggers:
    • $undefinedVariable triggers a notice (non-fatal).
    • nonExistentFunction() triggers a fatal error (E_ERROR).

Output Example

If you run the script:

  • For the notice ($undefinedVariable):
    [Notice] Undefined variable: undefinedVariable in /path/to/script.php on line 38
  • For the fatal error (nonExistentFunction):
    [Shutdown Error] Type: 1, Message: Call to undefined function nonExistentFunction() in /path/to/script.php on line 41

Errors are also logged to error.log.


Notes and Limitations

  1. Fatal Errors: Not all fatal errors can be caught (e.g., memory limit exhaustion or parse errors). The shutdown function catches most runtime fatal errors.
  2. Error Logging: Ensure the error.log file is writable by the web server (e.g., chmod 664 error.log and correct ownership).
  3. Production Environment: In production, set display_errors to Off and rely on error_log to avoid exposing sensitive information to users.
  4. Parse Errors: Parse errors (E_PARSE) occur before the script runs, so they can't be caught by a shutdown function. Enable display_errors or check the server error log to debug them.
  5. Error Types: The custom error handler can be extended to handle more error types (e.g., E_DEPRECATED, E_STRICT).

Testing the Setup

To test different error types, add these to the script:

// Notice
echo $undefined;

// Warning
fopen('nonexistent.txt', 'r');

// Fatal error
nonExistentFunction();

// User-triggered error
trigger_error('Custom error', E_USER_ERROR);

Check the output in the browser and the error.log file.


Additional Tips

  • Use a Debugger: Tools like Xdebug provide detailed stack traces and better error handling for development.
  • Error Handling Libraries: For larger applications, consider libraries like Monolog for advanced logging.
  • Try-Catch for Exceptions: For recoverable errors, use try-catch blocks:
    try {
        throw new Exception('Something went wrong!');
    } catch (Exception $e) {
        echo 'Caught exception: ', $e->getMessage();
    }