Stabilerer Code: Fehlerbehandlung mit try und catch in PHP5

Sie möchten, dass Ihr PHP-Programm stabiler wird? Dann achten Sie auf eine gute Fehlerbehandlung. Die aus anderen Programmiersprachen bekannten try-catch-Konstruktionen geben Programmierern ein mächtiges Werkzeug zur Fehlerkontrolle und Behandlung an die Hand. Dieser Beitrag zeigt, wie es geht.

Das Prinzip von try und catch: Im try-Block wird versucht, Code auszuführen, etwa eine Funktion oder eine Methode. Der catch-Block fängt die möglichen Fehler und Ausnahmen auf. Gibt es keinen Fehler, wird der Code nach dem try-catch-Block ausgeführt. Im Prinzip sieht das so aus:

<?php

try {

if (file_exists('unbekanntes_file.php'))

include 'unbekanntes_file.php';

else

throw new Exception('File not found');

}

catch (Exception $e) {

echo $e->getMessage();

echo ' in '.$e->getFile().', line: '.

$e->getLine().'.';

// Eventuell weiterführende Fehlerbehandlung...

}

?>

Hier überprüft der try-Block, ob eine Datei vorhanden ist. Falls nicht, wird mit throw eine Ausnahme erzeugt oder genau übersetzt “geworfen”. Die fängt das catch auf. Der Vorteil: im catch-Block können Sie selbst bestimmen, wie Sie mit dem Fehler umgehen.

Die Fehlermeldung selbst erhalten Sie mit der Methode getMessage(). Falls Sie noch einen Dateinamen und eine Zeilennummer zur Fehlermeldung dazu haben wollen, verwenden Sie getLine() und getFile().

Das Listing unten zeigt eine solche Klasse und die Fehlerbehandlung an einem einfachen Beispiel. Zur Erklärung: Die Klasse cTier enthält den Namen und die Anzahl der Beine eines Tieres. Die Methode setLegs setzt die Anzahl der Beine. setLegs prüft dabei zunächst, ob sie auch wirklich einen Integer-Wert erhalten hat. Falls nicht, löst sie mit throw einen Fehler der vorgefertigten Klasse Exception aus.

Anschließend prüft setLegs, ob sie den Wert 2 oder 4 als Argument erhalten hat (Insekten bleiben in diesem Beispiel außen vor). Falls nicht, löst die Methode einen anderen Fehler aus, nämlich LegException. Der ist als eigene, von Exception abgeleitete Klasse definiert. In dieser Klasse könnten Sie auch noch weitere Fehlerbehandlungs-Routinen definieren.

Im Beispiel bleibt sie aber identisch mit Exception. Nach dem Konstruktor versucht die Anweisung, im try-Block die Anzahl der Beine auf 5 zu setzen. Das erzeugt den Fehler, und das zweite catch fängt ihn auf. Es erscheint ein kurzer Hinweis auf Deutsch, bevor die englischsprachige Fehlermeldung folgt (das zur besseren Unterscheidung, welcher Teil der Fehlermeldung woher kommt – in Ihrem Programm sollten Sie ausschließlich bei einer Sprache bleiben).

Hier ist das Listing:

<?php

// Beispielklasse

class cTier

{

var $strName;

var $intLegs;

function __construct()

{

// Konstruktor

}

 

function setLegs($argIntLegs)

{

if (!is_int($argIntLegs))

throw new Exception('Wrong argument type: '.

$argIntLegs.'. <b>int</b> required.');

 

if (($argIntLegs !== 2) && ($argIntLegs !== 4))

throw new LegException('Wrong number of legs.

Should be 2 or 4.');

 

$this->intLegs = $argIntLegs;

}

}

class LegException extends Exception

{

function __construct($strMessage)

{

parent::__construct($strMessage);

}

}

// Hauptprogramm

$oSaeuger = new cTier();

try

{

//$oSaeuger->setLegs('garten');

$oSaeuger->setLegs(5);

}

catch (Exception $e)

{

echo 'Allgemeiner Fehler: '.$e->getMessage();

// Log-Eintrag schreiben, Mail an Admin...

}

catch (LegException $e)

{

echo 'Logischer Fehler: '.$e->getMessage();

// Hinweis auf Dokumentation...

}

?>

Try und Catch in der Praxs

Der Einsatz von try und catch geht weit über das in diesem Beitrag gezeigte Beispiel hinaus. Sie können:

  • eigene Fehlerklassen definieren – mehrere catch-Blöcke schreiben, um unterschiedliche Fehlermeldungen aufzufangen
  • in Klassen, Methoden und Funktionen Fehlermeldungen erzeugen, die erst in der aufrufenden Instanz aufgefangen werden.
  • try und catch nicht nur beim objektorientierten Programmieren verwenden. Es funktioniert genauso bei prozeduraler Programmierung. Statt Fehler mit return-Codes nach oben durchzureichen, nutzen Sie try und catch.
  • in jedem catch-Block noch weitere Fehlerbehandlungsmaßnahmen treffen, etwa das Programm abbrechen oder bestimmte Vorgänge rückgängig machen.

Sinnvoll ist der Einsatz von try-catch-Konstrukten vor allem da, wo Sie Klassenbibliotheken schreiben oder verwenden. Die Fehlerbehandlung können Sie dann bequem im aufrufenden Code abwickeln. Sie müssen sich nicht mit den Innereien der Bibliothek beschäftigen.

Fehler behandeln warum?

Das größte Problem für einen Programmierer ist der Benutzer. Was wie ein abschätziger Kalauer klingt, hat einen ernsten Hintergrund: Der Nutzer wird mit Ihrem Programm Dinge anstellen, die Sie sich nicht vorstellen können. Er wird Ihr Programm an die Grenzen führen – und unabsichtlich Fehler produzieren.

Der Grund: Der Benutzer hat eine andere Sichtweise, an ein Programm heranzugehen. Er kann Ihre Gedankengänge nicht erahnen, die Sie beim Planen und Programmieren eines Projektes hatten. Selbst wenn Sie ein Pflichtenheft haben der Nutzer wird sich immer anders verhalten, als Sie es erwarten.

Nicht nur wegen der Nutzer braucht Ihre Software eine robuste Fehlerbehandlung. Andere Umgebungen zur Laufzeit oder Wechselwirkungen mit anderen Programmen gehören zum Alltag Ihrer Software im täglichen Einsatz. Deshalb sollte sie auch auf unerwartete Fehler vorbereitet sein.

Dennoch müssen Sie jetzt nicht jede Anweisung mit einem try-catch-Konstrukt versehen. Denn das ist nur eine Methode, Fehler abzufangen. Andere Wege sind das Prüfen von Eingaben oder automatische Umleitungen, die einen Fehler automatisch umgehen.

Ähnliche Beiträge