Inhaltsverzeichnis
Definition
Exceptions sind Ausnahmebehandlungen im Programmcode.Die Verwendung ist einfach. Durch werfen von Exceptions mittels throw new Exception('foo') sorgt man dafür, dass der Programmfluss abbricht.
Durch Verwendung von try {} catch(Exception $e) kann man den Fehler dann behandeln ohne, dass der komplette Programmcode abbricht. Es gleicht der Abbruchbedingung in einer Schleife.
Das Spiel der Verantwortlichkeiten
Das spannende an Exceptions ist die Frage wo man sie am besten platziert und wie man sie verwendet.Objektorientierung und vor allem die Frage wo platziert man welchen Code ist ein Spiel mit Verantwortlichkeiten.
Ist es Aufgabe des Formulars (also dem "Controller") die Fehleingaben automatisch zu korrigieren, oder ist es Aufgabe des Benutzer Models optionale Angaben durch Defaults zu ersetzen.
Eine einfache Frage die ich häufig nutze um das Ganze zu erläutern ist: An welchen Stellen benötigt man die Funktion denn noch.
Wenn dann nicht sofort und ohne Zweifel eine Antwort kommt, dann heißt das doch, dass man die Funktion theoretisch überall einbauen kann.
Und damit gehört der Code an den abstraktesten Punkt an dem es möglich ist und was von überall verwendet wird.
Beispiel
Exceptions sind für Ausnahmen die man nicht automatisch auflösen kann oder will. Gehen wir von einem User Modell aus das auf dem abstraken Modell des Tutorials [wiki]Objektorientierung mit Models[/wiki] aufbaut.Quellcode
- class User extends Model {
- const MIN_PASSWORD_LENGTH = 8;
- public function validate() {
- $error = array();
- if(empty($this->firstname)) {
- $error['firstname'] = 'firstname';
- }
- if(strlen($this->password) < self::MIN_PASSWORD_LENGTH) {
- $error['password'] = 'to short';
- }
- if(count($error)) {
- throw new ValidateException($error);
- }
- }
- }
Man sieht, dass ich keine normale Exception Klasse gewählt habe, sondern stattdessen eine ValidateException verwende, die ein Array als Parameter empfängt. Das mache ich wegen der häufigen Anforderung, dass man mehrere Validierungen bei gleichzeitiger Benutzereingabe durchführt.
Die Klasse sieht wie folgt aus
Unbehandelete Exception
Speicher ich ein Formular mit fehlenden Daten ab, dann erhalte ich eine unbehandelete Exception die zum Abbruch des Programms führt:Die Ausgabe lautet wie folgt: Fatal error: Uncaught exception 'ValidateException' with message 'validation'
Behandelte Exception
Im konkreten Fall wollen wir den Benutzer bei einer Formulareingabe aber darauf aufmerksam machen, dass er seine Eingaben doch möglichst ergänzen soll.Dazu "fangen" wir die Exception und stellen die Fehlermeldungen dar. Der Programmfluss des Speicherns wurde beim throw new Exception abgebrochen - wir haben also keinen Speichervorgang durchgeführt.
Quellcode
- <?php
- function i18n($var) {
- return 'translation for '.$var;
- }
- $errors = array();
- $message = '';
- $user = null;
- if(count($_POST)) {
- $user = new User($_POST);
- try {
- $user->save();
- } catch(ValidateException $e) {
- $errors = $e->getErrors();
- foreach($errors as $error) {
- $message .= i18n('error.'.$error).'<br/>';
- }
- }
- }
- ?>
- <?= $message ?>
- <form method="post">
- <div<?if (array_key_exists('email', $errors)) echo ' style="background-color:#ffaaaa"' ?>>email:
- <input type="text" name="email" value="<?if($user) echo $user->email?>" />
- </div>
- <div<?if (array_key_exists('password', $errors)) echo ' style="background-color:#ffaaaa"' ?>>password:
- <input type="password" name="password" value="<?if($user) echo $user->password?>"/>
- </div>
- <div<?if (array_key_exists('firstname', $errors)) echo ' style="background-color:#ffaaaa"' ?>>firstname:
- <input type="text" name="firstname" value="<?if($user) echo $user->firstname?>"/>
- </div>
- <div<?if (array_key_exists('lastname', $errors)) echo ' style="background-color:#ffaaaa"' ?>>lastname:
- <input type="text" name="lastname" value="<?if($user) echo $user->lastname?>"/>
- </div>
- <input type="submit">
- </form>
7.712 mal gelesen