Fatal Error in PHP abfangen

PHP bietet genügend Möglichkeiten, um Fehler und Exception abzufangen und benutzerdefiniert zu verarbeiten. Die Funktionen set_error_handler() und set_exception_handler() seien als Grundlagen für jeden Entwickler an die Hand gelegt. Beispiele für die Implementation und den Einsatz sind zu Hauf im Netz vorhanden. Schnell schleicht sich der trügerische Gedanke ein, mit den beschriebenen Methoden alle Fehler abfangen zu können. Doch etliche fatale Fehler wie ein “Parse Error” bei z.B. Syntax-Fehlern im Skript oder einem “Fatal Error” bei z.B. einer Speicherüberschreitung können nicht mit den oben benannten Funktionen behandelt werden.

Doch beginnen wir mit einer eigenen Fehlerbehandlung nach dem PHP-Handbuch.

set_error_handler('my_error_handler');
function my_error_handler($errno,$errstr, $errfile,  $errline)
{
    switch($errno){
        case E_USER_ERROR:
        case E_ERROR:
        case E_PARSE:
        case E_CORE_ERROR:
        case E_COMPILE_ERROR:
            echo '<h1>Meine Fehlerausgabe</h1>';
            echo 'Entsprechende Fehlerausgabe...';
            exit(1);
        case E_USER_WARNING:
        //Weitere Behandlung von Warnungen, Hinweise....
    }
}
$foo = new Bar();

Ohne genaueres Studium (ok zugegeben – aufmerksames Lesen würde auch reichen) des entsprechenden Seite im Online-Handbuch, könnte man denken beim Aufruf dieses Skriptes, würde die eigene Fehlermeldung erscheinen – da die Klasse “Bar” ja gar nicht existiert oder bekannt ist.

Doch wie wir uns erinnern, werden mit dieser eigenen Fehlerbehandlung nicht alle Fehler abgefangen. Um folgende Fehler  handelt es sich dabei:

  • E_ERROR
    z.B. bei Überschreitung des Speicherlimits für das PHP-Skript (Bildergenerierung, etc.)
  • E_PARSE
    z.B. Syntax-Fehler im PHP-Skript
  • E_COMPILE_ERROR
    z.B. bei einer per “require” eingebunden Datei, die nicht existiert
  • E_CORE_ERROR
    Fehler beim Starten von PHP

Der obige Aufruf von “$foo = new Bar()” würde in diesem Fall einen E_ERROR werfen. Im folgenden Beispiel zeigen wir eine Vorgehensweise mit dem die Fehler E_ERROR, E_PARSE und E_COMPILE_ERROR benutzerdefiniert gefangen und behandelt werden können. Beim E_CORE_ERROR sind uns dann allerdings endgültig die Hände gebunden. Doch Hand aufs PHP-Herz, wer hat diese Fehlermeldung produktiv schon einmal erhalten?

Voraussetzung für das Abfangen obiger Fehler ist die Aktivierung der Ausgabepufferung, um die von PHP geworfenen Fehlermeldungen durch eigene Ausgaben überschreiben zu können. Dazu fehlt uns noch eine Funktion, die beim Beenden des PHP-Skriptes aufgerufen wird und (fast) fertig ist das Ganze. Erweitern wir also unser obiges Skript folgendermaßen:

obj_start();
set_error_handler('my_error_handler');
register_shutdown_function('my_shutdowm_handler');
 
function my_error_handler($errno,$errstr, $errfile,  $errline)
{
    switch($errno){
        case E_USER_ERROR:
        case E_ERROR:
        case E_PARSE:
        case E_CORE_ERROR:
        case E_COMPILE_ERROR:
            echo '<h1>Meine Fehlerausgabe</h1>';
            echo 'Entsprechende Fehlerausgabe...';
            exit(1);
        case E_USER_WARNING:
        //Weitere Behandlung von Warnungen, Hinweise....
    }
}
 
function my_shutdown_handler()
{
    if ($error = error_get_last()) {
        ob_end_clean();
        my_error_handler($error['type'], $error['message'], $error['file'], $error['line']);
    }
}
 
$foo = new Bar();
 
ob_end_flush();

Sobald unser PHP-Skript also beendet wird, überprüfen wir ob ein Fehler aufgetreten ist. Ist dies der Fall, übergeben wir die Fehlerdetails an unsere benutzerdefinierte Fehlerbehandlung und erhalten wie gewollt unsere eigene, wunderschön formatierte Fehlerbehandlung. Das Skript sollte natürlich nur als Anregung dienen und hat keinen Anspruch auf Vollständigkeit.

In diesem Sinne: Frohe Fehlerbehandlung…

Für diesen Blogbeitrag wurden wir inspiriert durch den englischen Artikel von Michael Caplan in seinem Blog:
Mayday, Mayday, Mayday – PHP Going Down

Über Markus Schmid (AREA-NET GmbH)

Als Geschäftsführer bei der AREA-NET GmbH zuständig für den Bereich App-Konzeption und -Entwicklung. Begeisterter Smartphone-Nutzer, Digital Native, Social Media Enthusiast und bekennender Kaffee-Trinker. Sie erreichen Markus Schmid unter www.xing.com/profile/Markus_Schmid11 oder de.linkedin.com/in/visitmarkusschmid

01. Juli 2010 von Markus Schmid (AREA-NET GmbH)
Kategorien: PHP, Softwareentwicklung | Schlagwörter: , , , , , , , | Schreibe einen Kommentar

Schreibe einen Kommentar

Pflichtfelder sind mit * markiert

*