PHP
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Functions
-
Section 4: Object-Oriented PHP
-
Section 5: Working with Data
-
Section 6: Modern PHP (PHP 8)
-
Section 7: Working with Files and Networking
-
Section 8: Common PHP Frameworks Overview
-
Section 9: Tooling and Ecosystem
-
Section 10: Practical Projects
-
Section 11: Interview Practice
-
Section 12: More Standard Library
-
Section 13: Data Structures and Algorithms in PHP
-
Section 14: More Practice Exercises
-
Section 15: More Security and Best Practices
-
Section 16: More Testing and Tooling
-
Section 17: WordPress-Style CMS Concepts
-
Section 18: Advanced OOP Practice
-
Section 19: More Web Fundamentals
-
Section 20: Database Practice
-
Section 21: PHP Manual: Array Functions
-
Section 22: PHP Manual: Date and Calendar Functions
-
Section 23: PHP Manual: Filesystem and Directory Functions
-
Section 24: PHP Manual: Filter and Var Handling
-
Section 25: PHP Manual: Math Functions
-
Section 26: PHP Manual: JSON and XML
-
Section 27: PHP Manual: Network and Stream Functions
-
Section 28: PHP Manual: Error and Exception Handling
-
Section 29: PHP Manual: Output Control and Misc
-
Section 30: PHP Manual: FTP, Zip, and Mail
-
Section 31: Modern PHP Frameworks Deep Dive
-
Section 32: PHP Design Patterns
-
Section 33: More Practice Exercises
-
Section 34: PHP Performance and Deployment
-
Section 35: More Interview Practice
-
Section 36: More PHP Standard Library
-
Section 37: PHP Concurrency and Async
-
Section 38: More Web Development Practice
-
Section 39: PHP Testing Deep Dive
-
Section 40: Composer and Package Development
-
Section 41: PHP Security Deep Dive
-
Section 42: More Practical Projects
-
Section 43: Legacy PHP Maintenance
-
Section 44: More Algorithm Practice
-
Section 45: Final Practice and Review
-
Section 46: PHP for E-Commerce Patterns
-
Section 47: PHP API Design Deep Dive
-
Section 48: PHP Caching Strategies
-
Section 49: PHP Queue and Background Jobs
-
Section 50: PHP Multi-Tenancy Patterns
-
Section 51: PHP Real-Time Features
-
Section 52: PHP CMS and Content Modeling
-
Section 53: PHP Internationalization
-
Section 54: More Framework-Specific Practice
-
Section 55: PHP Legacy Code Refactoring
-
Section 56: More Practice Projects Round 2
-
Section 57: PHP Command-Line Applications
-
Section 58: PHP and Microservices
-
Section 59: More Interview and Review Round 2
120: set_error_handler and set_exception_handler
I've spent a lot of time in the past staring at the "White Screen of Death" or, worse, seeing a raw PHP stack trace leaked to a client's browser. It's a nightmare for security and a terrible user experience. Usually, we wrap things in try...catch blocks, but in a large application, you can't possibly wrap every single line of code. You need a global safety net.
Watching the script crash
Let's look at a messy scenario. I'm building a small script that parses a weather API response. I'll intentionally write some brittle code to see how PHP handles it by default.
<?php
// Imagine this comes from an API
$weatherData = ['temp' => 72, 'city' => 'Austin'];
// I'm accessing a key that doesn't exist (Notice)
echo "Humidity: " . $weatherData['humidity'];
// And I'm throwing an exception that isn't caught (Fatal)
throw new Exception("API Connection Timeout!");
?>
If I run this, PHP first gives me a Warning: Undefined array key "humidity" and then it completely halts with an Uncaught Exception. In a local environment, this is helpful. In production, it's a disaster. I want to control how these are reported without cluttering my business logic with a thousand try-catch blocks.
Taming the PHP warnings
First, I want to deal with those annoying notices and warnings. PHP has a function called set_error_handler that lets me intercept these before they hit the screen. Let's try overriding the default behavior.
<?php
function myErrorHandler($errno, $errstr, $errfile, $errline) {
echo "<p style='color: orange;'>[Log]: Error ($errno) $errstr in $errfile on line $errline</p>";
// Return true to tell PHP we've handled it; otherwise, it might still trigger the internal handler
return true;
}
set_error_handler("myErrorHandler");
$weatherData = ['temp' => 72];
echo $weatherData['humidity']; // This now triggers my custom function
?>
Now, instead of the standard PHP warning, I get my custom orange message. I can now route this to a file, send it to a Slack channel, or just ignore it if it's a non-critical notice. One thing to keep in mind: set_error_handler doesn't catch "Fatal Errors" (like calling a function that doesn't exist). Those are too severe for this handler to intercept.
The safety net for uncaught exceptions
That brings us to the Exception I threw earlier. My error handler didn't touch it because exceptions aren't "errors" in the traditional PHP sense—they are objects. If an exception bubbles all the way up without being caught by a catch block, the script dies.
I can stop the crash by using set_exception_handler. This is basically the "last resort" catch block for the entire application.
<?php
function myExceptionHandler($exception) {
echo "<h1>Oops! Something went wrong</h1>";
echo "<p>Technical details: " . $exception->getMessage() . "</p>";
// In a real app, I'd log the stack trace to a file here
exit();
}
set_exception_handler("myExceptionHandler");
// This will no longer cause a raw PHP crash
throw new Exception("API Connection Timeout!");
?>
I love this approach because it separates my "happy path" logic from my "disaster recovery" logic. My main code just focuses on getting the weather, and these two handlers sit in the background, waiting to clean up the mess if something breaks.
Connecting the two
In a professional setup, you'd usually put these handlers in a bootstrap or config file that loads at the very start of the request. If you want to convert old-school PHP errors into exceptions so you only have to manage one handler, you can actually call error_trigger inside your error handler, or use a library that does this for you. But for most projects, having one handler for warnings/notices and one for uncaught exceptions is the sweet spot for stability.
📋 Practical Task
Building a Unified Crash-Report System for a User Import Script
You are writing a script that imports users from a CSV file. The script is prone to two types of failures: missing data in the CSV (which triggers PHP notices) and database connection failures (which trigger Exceptions).
Your task is to implement a global error and exception handling system with the following requirements:
- Create a
set_error_handlerthat catches notices/warnings and prints them in a<div>with a red border, prefixing the message with "CSV Data Issue: ". - Create a
set_exception_handlerthat catches any uncaught Exception, prints a user-friendly message ("The import process has been halted due to a system error"), and then logs the actual exception message to a file namederror_log.txtusingfile_put_contents(). - Test your handlers by:
- Attempting to access an undefined index in an array.
- Throwing a new
Exception("Database connection failed!").
There are no comments for now.