PHP Fundamentals

Error Types & Error Handling

13 min Lesson 26 of 45

Error Types & Error Handling

Understanding and properly handling errors is crucial for building robust PHP applications. PHP provides several error types and mechanisms to help you identify and resolve issues in your code.

PHP Error Types

PHP has several error levels that indicate the severity of different issues:

<?php // 1. Parse Errors (E_PARSE) - Fatal syntax errors // echo "Hello World // Missing closing quote - script won't run // 2. Fatal Errors (E_ERROR) - Critical errors that stop execution // callNonExistentFunction(); // Fatal error // 3. Warning Errors (E_WARNING) - Non-fatal errors, script continues $file = fopen("nonexistent.txt", "r"); // Warning: file not found // 4. Notice Errors (E_NOTICE) - Minor issues, script continues echo $undefinedVariable; // Notice: undefined variable // 5. Deprecated Errors (E_DEPRECATED) - Features that will be removed // Using old PHP features generates these warnings // 6. Strict Errors (E_STRICT) - Code improvement suggestions // Suggestions for better code practices ?>
Note: Fatal errors and parse errors will stop script execution immediately, while warnings and notices allow the script to continue running.

Error Reporting Configuration

You can control which errors are reported and how they are displayed:

<?php // Display all errors (for development) error_reporting(E_ALL); ini_set('display_errors', 1); // Display all errors except notices error_reporting(E_ALL & ~E_NOTICE); // Turn off error display (for production) error_reporting(0); ini_set('display_errors', 0); // Log errors to a file instead of displaying ini_set('log_errors', 1); ini_set('error_log', '/path/to/error.log'); // Common production configuration error_reporting(E_ALL); ini_set('display_errors', 0); ini_set('log_errors', 1); ?>
Warning: Never display errors in production! Always log them to a file and show user-friendly messages instead.

Custom Error Handlers

You can create custom error handlers to control how errors are processed:

<?php // Define a custom error handler function customErrorHandler($errno, $errstr, $errfile, $errline) { $errorTypes = [ E_ERROR => 'Error', E_WARNING => 'Warning', E_NOTICE => 'Notice', E_USER_ERROR => 'User Error', E_USER_WARNING => 'User Warning', E_USER_NOTICE => 'User Notice' ]; $type = $errorTypes[$errno] ?? 'Unknown Error'; // Log the error $message = "[$type] $errstr in $errfile on line $errline"; error_log($message); // Display user-friendly message echo "<div class='error'>An error occurred. Please try again later.</div>"; // For critical errors, stop execution if ($errno === E_ERROR || $errno === E_USER_ERROR) { die("Critical error - script terminated"); } return true; // Prevent PHP's default error handler } // Register the custom error handler set_error_handler('customErrorHandler'); // Trigger different error types trigger_error("This is a user notice", E_USER_NOTICE); trigger_error("This is a user warning", E_USER_WARNING); ?>

Triggering Custom Errors

You can trigger your own errors using the trigger_error() function:

<?php function divideNumbers($dividend, $divisor) { if ($divisor == 0) { trigger_error("Division by zero attempted", E_USER_WARNING); return false; } return $dividend / $divisor; } $result = divideNumbers(10, 0); if ($result === false) { echo "Operation failed"; } ?>

Error Suppression Operator

The @ operator suppresses error messages, but use it cautiously:

<?php // Without suppression - shows warning $content = file_get_contents('nonexistent.txt'); // With suppression - no warning displayed $content = @file_get_contents('nonexistent.txt'); // Better approach: check the result $content = @file_get_contents('nonexistent.txt'); if ($content === false) { echo "File could not be read"; } ?>
Tip: Instead of suppressing errors with @, it's better to check return values and handle errors explicitly.

Shutdown Function

Register a function to run when the script terminates, useful for catching fatal errors:

<?php function shutdownHandler() { $error = error_get_last(); if ($error !== null && $error['type'] === E_ERROR) { // Log fatal error error_log("Fatal error: " . $error['message']); // Display user-friendly message echo "<h1>Oops! Something went wrong</h1>"; echo "<p>We're working on fixing this issue.</p>"; } } register_shutdown_function('shutdownHandler'); // Your application code here ?>

Best Practices for Error Handling

<?php // 1. Development environment if ($_SERVER['SERVER_NAME'] === 'localhost') { error_reporting(E_ALL); ini_set('display_errors', 1); } else { // 2. Production environment error_reporting(E_ALL); ini_set('display_errors', 0); ini_set('log_errors', 1); ini_set('error_log', __DIR__ . '/logs/errors.log'); } // 3. Always validate user input function processAge($age) { if (!is_numeric($age)) { trigger_error("Age must be a number", E_USER_WARNING); return false; } if ($age < 0 || $age > 150) { trigger_error("Age is out of valid range", E_USER_WARNING); return false; } return true; } // 4. Check function return values $file = fopen("data.txt", "r"); if ($file === false) { error_log("Failed to open data.txt"); die("Unable to access required file"); } // 5. Use meaningful error messages trigger_error("Database connection failed: Invalid credentials", E_USER_ERROR); // Not just: trigger_error("Error", E_USER_ERROR); ?>

Logging Errors to File

<?php function logError($message, $level = 'ERROR') { $timestamp = date('Y-m-d H:i:s'); $logMessage = "[$timestamp] [$level] $message" . PHP_EOL; $logFile = __DIR__ . '/logs/app.log'; // Create logs directory if it doesn't exist $logDir = dirname($logFile); if (!is_dir($logDir)) { mkdir($logDir, 0755, true); } // Append to log file file_put_contents($logFile, $logMessage, FILE_APPEND); } // Usage logError("User authentication failed", 'WARNING'); logError("Database connection lost", 'CRITICAL'); logError("File uploaded successfully", 'INFO'); ?>
Exercise:
  1. Create a custom error handler that logs errors to a file with timestamps
  2. Write a function that reads a file and handles missing file errors gracefully
  3. Create a validation function that triggers appropriate errors for invalid email addresses
  4. Set up different error reporting levels for development and production environments

Common Mistakes to Avoid

<?php // ❌ Bad: Displaying errors in production ini_set('display_errors', 1); // Never do this in production! // ✅ Good: Log errors, don't display them ini_set('display_errors', 0); ini_set('log_errors', 1); // ❌ Bad: Suppressing all errors @include('config.php'); @$result = $dangerous_operation; // ✅ Good: Handle errors explicitly if (file_exists('config.php')) { include('config.php'); } else { error_log('Config file missing'); die('Configuration error'); } // ❌ Bad: Generic error messages trigger_error("Error", E_USER_ERROR); // ✅ Good: Descriptive error messages trigger_error("Failed to connect to database: Connection timeout", E_USER_ERROR); ?>
Production Checklist:
  • Turn off error display: display_errors = 0
  • Enable error logging: log_errors = 1
  • Set error log path: error_log = /path/to/logs
  • Report all errors: error_reporting = E_ALL
  • Use custom error pages for user-facing errors