set_error_handler()
PHP-Fehlerbehandlung mit set_error_handler(): Callback registrieren, Fehler abfangen und in Ausnahmen umwandeln.
PHPs Standardverhalten bei einem nicht-fatalen Fehler besteht darin, eine Meldung in die Ausgabe zu schreiben (oder zu protokollieren) und weiterzulaufen. In der Produktion ist das selten erwünscht: Die rohe Meldung kann Dateipfade an Besucher weitergeben, und es gibt keinen zentralen Ort zum Protokollieren, Formatieren oder Umwandeln von Fehlern. Die Funktion set_error_handler() behebt dies, indem sie PHPs eingebaute Fehler durch eine selbst definierte Funktion leitet.
Dieses Kapitel erklärt, was set_error_handler() tut, die genaue Callback-Signatur, die PHP erwartet, welche Fehler es abfangen kann und welche nicht, und wie man es für sauberes Protokollieren einsetzt.
Was set_error_handler() tut
set_error_handler() registriert einen Callback, den PHP anstelle seines eingebauten Fehler-Handlers aufruft, wenn ein passender (nicht-fataler) Fehler ausgelöst wird. Der Callback entscheidet, was als Nächstes passiert — protokollieren, eine benutzerfreundliche Meldung anzeigen, eine Ausnahme werfen oder den Fehler stillschweigend ignorieren.
Es stoppt nicht das Auslösen von Fehlern; es ändert nur, wie sie behandelt werden. PHP respektiert weiterhin error_reporting, wenn es entscheidet, ob der Handler überhaupt aufgerufen wird.
Syntax
set_error_handler(
callable|null $callback,
int $error_levels = E_ALL
): callable|false| Parameter | Beschreibung |
|---|---|
$callback | Die Funktion, die PHP aufruft, wenn ein Fehler auftritt. null übergeben, um PHPs eingebauten Handler wiederherzustellen. |
$error_levels | Eine Bitmaske der Fehlerebenen, die der Handler empfangen soll (z. B. E_WARNING | E_NOTICE). Standardmäßig E_ALL. |
Rückgabewert: der zuvor registrierte Handler (ein Callable) oder null, wenn keiner vorhanden war. Gibt false zurück, wenn der Callback ungültig ist.
Die Callback-Signatur
PHP ruft den Handler mit bis zu fünf Argumenten auf. Die ersten vier sind die am häufigsten verwendeten:
function handler(
int $errno, // the error level constant, e.g. E_WARNING
string $errstr, // the error message
string $errfile = "", // file where the error occurred
int $errline = 0 // line number
): bool {
// ...
}Wenn der Handler false zurückgibt, setzt PHP danach seine normale interne Fehlerbehandlung fort. Die Rückgabe von true (oder nichts) signalisiert PHP, dass der Fehler vollständig behandelt wurde, und unterdrückt das Standardverhalten.
Welche Fehler abgefangen werden können
set_error_handler() fängt die vom Benutzer abfangbaren Fehlerebenen ab — Warnungen, Hinweise, Deprecation-Meldungen und die E_USER_*-Familie, die durch trigger_error() ausgelöst wird:
| Abfangbar | Nicht abfangbar (fatal) |
|---|---|
E_WARNING, E_NOTICE, E_DEPRECATED | E_ERROR |
E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE | E_PARSE |
E_RECOVERABLE_ERROR, E_STRICT | E_CORE_ERROR, E_COMPILE_ERROR |
Hinweis: Fatale Fehler wie
E_ERRORundE_PARSEumgehen den Handler und beenden das Skript. Um diese zu erfassen, kombiniert man den Handler mitset_exception_handler()und einer Shutdown-Funktion. Nicht abgefangene Ausnahmen werden hier ebenfalls nicht weitergeleitet — sie haben ihren eigenen Handler.
Ein einfacher Handler
Eine Funktion mit der erwarteten Signatur definieren und registrieren. Hier simuliert ein trigger_error()-Aufruf eine Warnung, damit der Handler sichtbar ausgeführt wird:
<?php
function customErrorHandler($errno, $errstr, $errfile, $errline)
{
echo "Handled error [$errno]: $errstr in $errfile on line $errline\n";
return true; // we consider the error fully handled
}
set_error_handler("customErrorHandler");
trigger_error("This is a test warning", E_USER_WARNING);
// Restore PHP's default error handling
restore_error_handler();Ausgabe:
Handled error [512]: This is a test warning in ... on line 11512 ist der numerische Wert von E_USER_WARNING. Nach restore_error_handler() fällt die Fehlerbehandlung wieder auf PHPs Standardverhalten zurück.
Fehler in Ausnahmen umwandeln
Ein verbreitetes Produktionsmuster ist es, Warnungen und Hinweise in Ausnahmen umzuwandeln, damit sie durch die normale try/catch-Logik fließen. So kann ein fehlgeschlagener file_get_contents()-Aufruf (der nur eine Warnung erzeugt) mit try/catch behandelt werden:
<?php
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
// Respect the @ operator and error_reporting settings.
if (!(error_reporting() & $errno)) {
return false;
}
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});
try {
$data = file_get_contents("/no/such/file");
} catch (ErrorException $e) {
echo "Caught: " . $e->getMessage() . "\n";
}Ausgabe:
Caught: file_get_contents(/no/such/file): Failed to open stream: No such file or directoryProtokollieren statt Anzeigen
Die Zuordnung der Levelkonstante zu einem lesbaren Label hält Protokolle übersichtlich. Mit error_log() wird in das konfigurierte Protokollziel geschrieben:
<?php
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
$levels = [
E_WARNING => "WARNING",
E_NOTICE => "NOTICE",
E_DEPRECATED => "DEPRECATED",
E_USER_WARNING => "USER_WARNING",
];
$label = $levels[$errno] ?? "UNKNOWN($errno)";
$line = "[$label] $errstr in $errfile:$errline";
error_log($line); // goes to your log, not the page
echo $line . "\n"; // shown here only to demonstrate the output
return true;
});
trigger_error("Disk space low", E_USER_WARNING);Ausgabe:
[USER_WARNING] Disk space low in ... :15Fallstricke
- Der
@-Operator. Wenn ein Fehler mit@unterdrückt wird, gibterror_reporting()im Handler0zurück.error_reporting() & $errnoprüfen, wenn@berücksichtigt werden soll, wie oben gezeigt. - Fatale Fehler entgehen dem Handler. Unabhängig vom zweiten Argument werden
E_ERRORund Parse-Fehler niemals an den Handler übergeben. - Er ist global. Ein registrierter Handler wirkt sich auf die gesamte Anfrage aus. Bibliotheken, die ihren eigenen Handler setzen, können den eigenen überschreiben — daher Handler nach Gebrauch wiederherstellen.
- Kein
echoin der Produktion. Das Anzeigen roher Meldungen gibt Pfade preis und hilft Angreifern — stattdessen protokollieren und eine generische Seite anzeigen.
Verwandte Funktionen
restore_error_handler()— zum vorherigen Handler zurückwechseln.trigger_error()— eigeneE_USER_*-Fehler auslösen.error_reporting()— steuern, welche Ebenen aktiv sind.set_exception_handler()— nicht abgefangene Ausnahmen abfangen.
Fazit
set_error_handler() bietet einen zentralen Ort, um PHPs nicht-fatale Fehler abzufangen und eigene Logik anzuwenden — protokollieren, in Ausnahmen umwandeln oder vor Benutzern verbergen. Für produktionsreife Fehlerbehandlung mit einem Exception-Handler und ordentlichem Logging kombinieren. Eine harte Grenze ist zu beachten: Fatale Fehler und Parse-Fehler umgehen den Handler vollständig.