PHP Post-Mortem Debugger

2026 update: I originally wrote this snippet over a decade ago. While modern tools like Xdebug and framework exception handlers cover most debugging needs, this technique can still help when PHP fails before normal error handling kicks in. Admittedly, I still use it from time to time when faced with issues in old codebases.

PHP is very configurable, but sometimes default settings or those imposed by the framework in use tend to make simple debugging very difficult.

Don’t get me wrong, whenever possible a proper debugger such as Xdebug is the way to go. But sometimes, when all else fails, and you’re facing a blank white page, the snippet below can get you out of the situation in no time.

 1<?php
 2
 3register_shutdown_function(static function () {
 4	while (ob_get_level() > 0) {
 5	    ob_end_clean();
 6	}
 7	ob_implicit_flush(true);
 8
 9	echo "<!--\n";
10
11	echo "\n\tHeaders Sent:";
12	$file = $line = null;
13	headers_sent($file, $line);
14	$file = empty($file) ? 'unknown' : $file;
15	echo "\n\t\tat $file:$line";
16
17	echo "\n\tLast Error:";
18	$lastError = error_get_last();
19	if (!empty($lastError)) {
20	    foreach (get_defined_constants(true)['Core'] as $name => $constantValue) {
21            if (substr($name, 0, 2) === 'E_' && $constantValue === $lastError['type']) {
22                $lastError['type'] = $name;
23                break;
24            }
25        }
26		echo str_replace("\n", "\n\t\t", htmlspecialchars("\n{$lastError['message']} ({$lastError['type']}) in {$lastError['file']}:{$lastError['line']}"));
27	} else {
28		echo "\n\t\tnone";
29	}
30
31	echo "\n\tIncluded Files:";
32	echo "\n\t\t" . implode("\n\t\t", get_included_files());
33	
34	echo "\n-->";
35});
36

So, how does it work?

While a long time has passed since I first wrote it, little changed in the way it works.

As you might know, in PHP you can register a shutdown handler – a function to be called when PHP is closing down. What you might not know is that this function is called even when many fatal errors occur, making it useful for retrieving debugging information during otherwise unrecoverable failures.

This functionality makes it a good candidate for retrieving interesting information on the current page run, such as:

All this is conveniently rendered inside an HTML comment to (hopefully) prevent anything visible from appearing in HTML responses. Of course, use this script with care, it may easily expose internal server details such as system paths.

Unless otherwise and clearly specified: