PHP Try ... Catch – Exception Handling

Exceptions dienen der Behandlung von gegebenenfalls während der Ausführung eines Scripts auftretenden Fehlern. Läuft während der Verarbeitung eines PHP-Scripts etwas nicht so, wie es eigentlich soll, so führt dies häufig dazu, dass Variablen mit ungültigen Werten gefüllt sind. Der Zustand, in dem sich das Script befindet, ist dann nicht so, wie es sich der PHP Programmierer ursprünglich gedacht hat. Ein solcher unvorhergesehener Zustand führt meist auch zu Folgefehlern, die unter Umständen fatale Auswirkungen haben können – etwa wenn Daten in einer Datei oder der Datenbank abgelegt werden sollen.

Mit Hilfe von PHP Exceptions ist es nun möglich, an den Stellen im Script, an denen die Verarbeitung unter Umständen problematisch werden könnte, entsprechend vorzusorgen. Insbesondere wenn im Verlauf des Scripts auf externe Datenquellen zugegriffen wird ist es sinnvoll mit entsprechenden Ausnahmebehandlungen vorzusorgen. Aber auch wenn Benutzereingaben verarbeitet werden, sollte auf rehlerhafte Eingaben reagiert werden. Dazu wird um einen potenziell kritischen Teil im Code ein Exception-Block gelegt, der die jeweiligen Fehler abfängt und dafür sorgt, dass der Zustand des Scripts wieder zurecht gerückt wird. Dabei sollte der Entwickler die kritischen Variablen mit gültigen Werten füllen oder im weiteren Ablauf verwendete Statusinformationen aktualisieren. Ist dies nicht nötig, so kann die Ausgabe einer beschreibenden Fehlermeldung erfolgen – gegebenen Falls mit Angabe des Files, in dem der Code steckt und der Zeilennummer, in welcher der Fehler aufgetreten ist. Bitte beachten Sie, dass Exceptions erst ab der PHP Version 5 funktionieren.

PHP Exception Beispiel: Abfangen von Fehlern

Folgendes try-catch Beispiel dividiert die Variable a (Dividend) durch verschiedene Werte aus Variable b, deren unterschiedliche Werte über eine Schleife gesetzt werden. Enthält die Variable zur Speicherung des Divisors (b) den Wert 0, so ist diese Operation nicht definiert und es muss eine entsprechende Behandlung des aufgetretenen Fehlers erfolgen. Dies geschieht dann auch im Catch-Teil im Schleifeninneren. Mit echo erfolgt hier die Ausgabe der in der Exception-Instanz gespeicherten Werte – hier werden alle durch Methoden der Exception-Klasse definierten Funktionen aufgerufen, die entsprechende Informationen für die Ausgaben liefern.

<?php
    // Variable zur Speicherung des Zählers
    $a = 1;
    // Der Nenner wird durch eine Zählervariable (counter) vorgegeben
    for ($b = 0; $b < 3; $b++) {
        try {
            // Bedingung, unter der eine Exception geworfen werden muss
            if ($b == 0)
                // Bedingung trifft zu:
                // Auslösen der Exception erfolgt über das throw-Statement
                // Ab hier wird die Ausführung abgebrochen und im nächsten
                // Catch-Block, der die Exception abfängt fortgesetzt.
                // Die Fehlermeldung und der Fehlercode kann im Constructor
                // angegeben werden. Dieser setzt die entsprechenden Daten
                // für die Exception-Instanz.
                throw new Exception ('Division durch 0 ist nicht definiert!', 42);
            // Bedingung trifft nicht zu! Bis hier ist also alles gut gegangen
            // und es kann ganz normal weiter gehen.
            $c = $a / $b;
            echo 'a / b = ' . ($a / $b) . '<br>';
        } catch (Exception $e) {
            // Exception-Block, der nur dann ausgeführt wird, wenn eine
            // Exception auftritt.
            // Hier werden die Informationen zur aufgetretenen Exception
            // einfach ausgegeben. Diese werden durch Methoden des
            // vordefinierten Exception-Objekts abgefragt.
            echo 'Es wurde eine Exception geworfen:<br>' .
                 // getFile liefert die Datei, in der die Exception
                 // geworden wurde
                 'Datei: ' . $e->getFile () . '<br>' .
                 // getLine die Zeile innerhalb der Datei, an welcher
                 // der Fehler auftrat
                 'Zeile: ' . $e->getLine () . '<br>' .
                 // getTrace liefert ein Array, in dem die Aufrufstruktur
                 // detailiert beschrieben wird. Alle beteiligten Dateien
                 // und Aufrufe liegen mit Zeilennummern vor.
                 'Trace: ' . $e->getTrace () . '<br>' .
                 // getTraceAsString enthält die Kurzform der Aufrufstruktur
                 'Trace als String: ' . $e->getTraceAsString () . '<br>' .
                 // Der Fehlercode der Exception wird durch getCode geliefert
                 'Fehlercode: ' . $e->getCode () . '<br>' .
                 // Mit getMessage kann die Fehlermeldung abgerufen werden
                 'Meldung: ' . $e->getMessage () . '<br>';
        }
    }
?>

Es wurde eine Exception geworfen:
Datei: /srv/www/htdocs/_PHPTEST.php
Zeile: 147
Trace: Array
Trace als String: #0 {main}
Fehlercode: 42
Meldung: Division durch 0 ist nicht definiert!
a / b = 1
a / b = 0.5

PHP Throw Exception: Werfen bzw. Auslösen von Ausnahmefällen

Nachfolgend wird das PHP Sprachkonstrukt Try-Catch innerhalb einer Function verwendet. Der auskommentierte Scriptteil zeigt, wie Exceptions grundsätzlich geworfen werden müssen – allerdings wird das Throw-Exception nicht von einem Catch-Block umgeben, was unweigerlich zu einem Abbruch des Scripts führen würde. Darauf folgt die Definition einer Funktion, die – abhängig von internen Abfragen – mit Throw eine Exception wirft.

Der darauf folgende Try-Catch-Block umschließt den Funktionsaufruf und stellt damit sicher, dass auftretende Exceptions abgefangen werden. Im Catch-Teil werden dann wiederum Informationen zur eventuell aufgetretenen Exception ausgegeben. Alle in der Exception-Instanz enthaltenen Daten werden durch den Aufruf von var_dump strukturiert auf der Ergebnisseite dargestellt. Danach wird unter Catch noch dafür gesorgt, dass die Variable i initialisiert wird und damit ein gültiger Zustand gesetzt.

<?php
    // Folgendes Try-Catch-Beispiel führt zum Abbruch der Verarbeitung, da eine
    // Exception geworfen wird, die nicht abgefangen wird. Um keinen vorzeitigen
    // Abbruch des Scripts zu riskieren, muss das Throw-Statement von einem
    // zugehörigen Try-Catch-Block mit der zugehörigen Ausnahmebehandlung
    // umgeben sein.
    //if (!isset ($i))
    //    throw new Exception ('Variable nicht definiert!');


    // Funktion definieren, die über Throw eine Exception wirft, wenn die im Parameter
    // angegebene Variable nicht definiert ist
    function gibts_das ($value) {
        if (isset ($value))
            echo 'Ist definiert!';
        else
            // Mit Throw Exception mit spezieller Meldung und einem Fehlercode
            // werfen.
            throw new Exception ('Gibts nicht Exception!', 815);
    }

    // Da in der Funktion Exceptions auftreten können ist es grundsätzlich
    // angebracht einen Try-Catch-Block um Aufrufe der Funktion zu legen.
    // Wird dies versäumt, so werden die Informationen, die dieser Mechanismus
    // bereit stellt, auch nicht ausgegeben. Auch eine Reaktion auf ggf.
    // auftretende Ausnahmefälle (Exceptions) ist somit nicht möglich.
    try {
        gibts_das ($i);
    } catch (Exception $e) {
        // Komplette Struktur der Exception-Instanz ausgeben
        // Der Übersicht halber wird das ganze Array durch das HTML-Tag
        // PRE vorformatiert ausgegeben.
        echo "<pre>In der Exception-Instanz enthaltene Daten:\n";
        var_dump ($e);
        echo "Aufrufstruktur:\n" . $e->getTraceAsString ();
        echo "</pre>";
        // Für die weitere Verarbeitung des Scripts sollte hier auch ein
        // definierter Zustand hergestellt werden, mit der es nach Auftreten
        // der Exception weiter gehen kann.
        $i = 0;
    }
    // Hier kann es nun im Code mit der Sicherheit weiter gehen, dass i
    // einen gültigen Wert enthält.
?>

In der Exception-Instanz enthaltene Daten:
object(Exception)#1 (6) {
  ["message:protected"]=>
  string(22) "Gibts nicht Exception!"
  ["string:private"]=>
  string(0) ""
  ["code:protected"]=>
  int(815)
  ["file:protected"]=>
  string(67) "/srv/www/htdocs/_PHPTEST.php"
  ["line:protected"]=>
  int(151)
  ["trace:private"]=>
  array(1) {
    [0]=>
    array(4) {
      ["file"]=>
      string(67) "/srv/www/htdocs/_PHPTEST.php"
      ["line"]=>
      int(160)
      ["function"]=>
      string(9) "gibts_das"
      ["args"]=>
      array(1) {
        [0]=>
        NULL
      }
    }
  }
}
Aufrufstruktur:
#0 /srv/www/htdocs/_PHPTEST.php(160): gibts_das(NULL)
#1 {main}


Fatal error: Uncaught Error: Call to undefined function ereg() in /homepages/26/d102044405/htdocs/_WEB_FORUM_EVO_/forum_last.php:6 Stack trace: #0 {main} thrown in /homepages/26/d102044405/htdocs/_WEB_FORUM_EVO_/forum_last.php on line 6

¬ Tutorials



¬ Insolvenzrecht