Categories: PHP

Fehlerbehandlung mit Exceptions in PHP 5

In PHP 4 wurde die Fehlerbehandlung aus Funktionen oder Methoden mithilfe der return-Anweisung zurückgegeben. Nehmen wir zum Beispiel an, wir möchten innerhalb einer Methode oder Funktion eine MySQLi-Verbindung aufbauen. Beim Scheitern der Verbindung soll eine Fehlermeldung sowie der zugehörige Fehlercode ausgegeben werden. In PHP 4 hätte die Fehlerbehandlung so ausgesehen:

function connect_to_mysql()
{$mysqli = @new mysqli('localhost', 'username', 'password', 'db_name');
if ($mysqli->connect_errno)
{
return false;}
return true;
}

Möchten wir nun herausfinden, ob die Verbindung zur Datenbank erfolgreich hergestellt worden ist oder nicht, müssen wir den Rückgabewert der Funktion überprüfen.

if(connect_to_mysql() == false)
{echo "Es konnte keine Verbindung zur Datenbank hergestellt werden.";
die();
}

Haben wir jetzt zum Beispiel noch weitere Funktionen fürs Einfügen neuer Einträge in die Datenbank oder fürs Selektieren von Einträgen, so müssen wir für jede Funktion einzeln überprüfen, ob ein Fehler aufgetreten ist oder nicht. Bauen die einzelnen Funktionsaufrufe aufeinander auf, so ist dies umso wichtiger.

In PHP 5 ist die Fehlerbehandlung innerhalb von Klassen nun mittels Exceptions möglich. Die Klassenmethode connect_to_mysql() würde in PHP 5 mit Exceptions so aussehen:

public function connect_to_mysql()
{$mysqli = @new mysqli('localhost', 'username', 'password', 'db_name');
if ($mysqli->connect_errno)
{
throw new Exception('Es konnte keine Verbindung zur Datenbank hergestellt werden.');}
}

Im Skript, das die Klassenmethode aufruft, fällt jetzt die explizite Überprüfung auf den Rückgabewert weg. Die Abarbeitung des Skripts wird unterbrochen sobald eine Exception auftritt. Dies ist vermutlich einer der größten Vorteile von Exceptions. Wenn Du Dir das nächste Beispiel einmal anschaust, siehst Du, dass wir nicht überprüfen müssen, ob die Datenbankverbindung erfolgreich hergestellt wurde bevor wir die Methode insert_values aufrufen können. Wir müssen nicht jeden Rückgabewert überprüfen, um sicher zu sein, dass keine Folgefehler auftreten, da das Script automatisch alle folgenden Anweisungen bis zum nächsten catch-Block überspringt, sollte eine Exception auftreten.

Um die Exception verarbeiten zu können, muss der Code, der die Klassenmethode aufruft, sich innerhalb eines try/catch-Blocks befinden.

try
{$someclass->connect_to_mysql();
$someclass->insert_values($arr);
}
catch(Exception $e)
{echo "Es ist ein Fehler aufgetreten.";
}

Die Ausgabe der Exception ist bisher noch nicht sehr informativ und spezifisch. Die Exception-Klasse lässt sich nutzen, um aussagekräftige und spezifische Fehlermeldungen ausgeben zu können. Sie verfügt über verschiedene Methoden, mit denen die Ausgabe angepasst werden kann. Dazu gehören die Methoden getMessage() (Gibt die Fehlermeldung aus dem Konstruktor der Exception zurück), getCode() (Gibt den Fehlercode aus dem Konstruktor der Exception zurück), getFile() (Gibt den namen der Datei zurück, in der die Exception auftrat), getTrace() (Gibt ein Array mit der Ablaufverfolgung der Exception zurück (mehr dazu hier)).

Lass uns die Exception-Methoden verwenden, um eine effektivere Fehlermeldung zu erstellen. Wenn eine Exception auftritt, möchten wir den Dateinamen, in dem der Fehler auftrat, sowie die Zeilennummer anzeigen. Außerdem soll die Nachricht ausgegeben werden, die in den Konstruktor der Exception eingegeben wurde.

try
{$someclass->connect_to_mysql();
$someclass->insert_values($arr);
}
catch(Exception $e)
{echo "An error occured.\n";
echo "Line Number: ".$e->getLine()."\n";
echo "File Name: ".$e->getFile()."\n";
echo "Error Description: ".$e->getMessage();
}

Jetzt da wir erfahren haben wie man Exceptions erstellt, gibt es noch eine Sache, die Du wissen solltest. Stelle Dir vor, Du möchtest Daten aus einer Datei auf Deinem Server auslesen, dann validieren und anschließend in eine Datenbank schreiben. Jede dieser Aktionen kann zu unterschiedlichen Arten von Fehlern führen. Im ersten Fall wirst Du Fehler bekommen, die mit dem Dateisystem zu tun haben, z.B. ein Fehler beim Laden oder Lesen der Datei. Im zweiten Fall Fehler, die mit der Validierung zu tun haben, z.B. ein falscher Datentyp. Im dritten Fall wirst Du womöglich Fehler mit der Datenbankanbindung haben, z.B. beim Verbinden mit der Datenbank oder dem Einfügen neuer Daten. Was ich Dir sagen möchte ist, dass es unterschiedliche Arten von Fehlern gibt und es somit schön wäre, wenn man diese Fehler in verschiedene Gruppen aufteilen könnte. Um das zu tun können wir Unterklassen der Exception-Klasse erstellen.

class FileException extends Exception // Exceptions für Fehler mit dem Dateisystem
{
}
class ValidateException extends Exception // Exceptions für Fehler beim Validieren
{
}
class SQLException extends Exception // Exceptions für Fehler mit der Datenbankanbindung
{
}

Wenn ein Fehler in unserem Skript auftraucht, können wir nun den korrekten Exception-Typ dafür verwenden, zum Beispiel:

function connect_to_mysql()
{$mysqli = @new mysqli('localhost', 'username', 'password', 'db_name');
if ($mysqli->connect_errno)
{
throw new SQLException('Es konnte keine Verbindung zur Datenbank hergestellt werden.');}
return true;
}

Wir können den try/catch-Block so lassen wie wir ihn oben geschrieben haben. catch(Exception $e) wird alle Exceptions abfangen, die wir erstellt haben, auch Unterklassen. Wenn Du unterschiedliche Fehlermeldungen für die verschiedenen Unterklassen definieren möchtest, kannst Du natürlich auch catch(FileException $e), catch(ValidateException $e) und catch(SQLException $e) nutzen.

Beachte, dass es in der Standard PHP Library bereits einige vordefinierte Exceptions gibt, die den Vorteil bieten, dass sie allgemein bekannt sind und häufig genutzt werden. Durch die Benutzung von SPL-Exceptions erstellen Programmierer einen Standard, der es anderen Programmieren nachher vereinfacht sich in fremden Code einzuarbeiten ohne sich die Exception-Struktur genauer anschauen zu müssen. Wenn Du mehr über SPL-Exceptions erfahren möchtest, lies Dir am besten diese Anleitung für die korrekte Benutzung von Exceptions durch (englisch).

Chris @Lingulocom

I am a frontend and backend web developer who loves building up new projects from scratch. In my blog "Lingulo" me and some guest authors regularly post new tutorials, web design trends or useful resources.

Share
Published by

Recent Posts

The Best Programming Languages for Enterprise Software Development

Over the last decade, both enterprises and the world of programming have witnessed big changes. With the introduction of new…

4 years ago

Why Small Businesses Are Creating Their Own Apps

No matter the size of your company, developing the right app with the right team can have an outsized return…

4 years ago

3 Exceptional PR Campaigns to Inspire Your Business

The best PR campaigns are memorable and distinctive. They can go viral, get press coverage, and, ultimately, help your brand…

4 years ago

How COVID-19 has changed the restaurant delivery app industry

2020 has been dubbed “the year of change” and it’s quite easy to see why that is. COVID-19 has put…

4 years ago

What are the Best Programming Languages to Learn for a Career in FinTech?

If you’re thinking about a career in FinTech, then you’ll also need to know the best programming languages to learn.…

4 years ago

How to Create a Catchy Logo for Your Website?

If you want to create a catchy logo for your website, then you are in the right place because today,…

4 years ago