// der php hacker

// archiv

Warum die() so oft falsch eingesetzt wird

Geschrieben am 27. Apr 2009 von Cem Derin

Wir kennen die Funktion alle: die(). Bewirkt einen sofortigen Abbruch der Ausführung des Scriptes und ermöglicht ein allerletztes Lebenszeichen aus dem Script heraus. Anzutreffen vor allem als Debug-Werkzeug, wenn kein Debugger zur Verfügung steht. Allerdings ist diese Funktion darüber hinaus auch noch zu fragwürdiger Bekanntheit in einer Unzahl von Tutorials gelangt. Warum “fragwürdig” und warum “die();” im Grunde nicht eingesetzt werden sollte, möchte ich im folgenden erklären.

Noch einmal möchte ich kurz auf die wahrscheinlich häufigste Verwendung von die() zu sprechen kommen: In Zusammenhang mit Datenbankoperationen. Jeder ist schon einmal an solch einem Code vorbeigestolpert:

$connection = mysql_connect('localhost', 'root', '')
               or die(mysql_error());

Das ist aus vielerlei Gründen schlechter Stil. Als erstes ist es ein No-Go Systemfehler auf Live-Systemen auszugeben. Wie sehen hier, dass keine Unterscheidung getroffen wird, auf was für einer Art System wir uns derzeit befinden. Darüber hinaus wird die Anwendung sofort angebrochen – in der Regel will man das jedoch nicht bzw. es ist nicht nötig. Eine qualifizierte Fehlermeldung an den Benutzer wäre hier angebrachter als ein unkontrollierter Abbruch des Scriptes – wir sind froh, dass es Garbage Collection gibt.

Ein Eingang, ein Ausgang

Eine Webapplikation mit PHP sollte so gebaut sein, dass sie genau einen Eingang und einen Ausgang besitzt. Das bedeutet, dass Daten über einen genau definierten und damit kontrollierten Weg in die Applikation fließen, und nicht anders. Genau so fließt das, was an den Client ausgegeben wird auch einen genau definierten Weg entlang.

Schnell macht sich das Dilemma bemerkbar, wenn die(); diesen Ablauf stört. Im Laufe des dispatchings können auch nach dem Auftritt eines Fehlers noch wichtige Aktionen ausgeführt werden – was man mit diesem die-Befehl verhindern würde. Bestenfalls unterstützt man unstrukturierte Architektur, in dem Datenwege nicht mehr klar sind, im schlimmsten Fall erzeugt man unbrauchbare Logs oder gar Race Conditions.

Tritt beispielsweise ein Problem wie das oben beschriebe auf, dass eine Datenbank nicht verfügbar ist, so stellt dies eine “Ausnahme” des geplanten Programmflusses dar. Ausnahme heißt auf englisch Exception. In der Objektorientierten Programmierung wirft man Exceptions. Und was geworfen wird, kann auch gefangen werden. Dafür muss man allerdings bereit stehen. Um geworfene Exceptions zu fangen, stellt PHP einem das try … catch Konstrukt zur Verfügung.

Wir sehen also: Ein die() ist nicht nötig. Statt alles abzubrechen und wegzurennen, werfen wir eine Exception. Diese wird entweder gefangen und der Fehler kann kontrolliert behandelt werden, oder eben nicht: Dann bricht das Script so oder so ab … sollte natürlich nie soweit kommen ;-)

Warum die nicht sterben sollte

Ich gehe allerdings nicht so weit, dass ich verlange, dass die() aus PHP entfernt werden soll – was Brian fast schon vorschlägt. Dieser Befehl ist weiterhin wichtig. So lange PHP nicht mit einem eingebauten Debugger daher kommt, kann man sicher sein, dass man eben einen solchen verwenden kann. Dahingehend leistet die(); einem gute Dienste. Beruflich kann ich derzeit beispielsweise nicht Debuggen – und bin froh, dass es die gibt.


#001
23. Apr 2009

die() ist für mich sowas wie “mach auf gar keinen Fall weiter” oder “bis hier und keinen Schritt weiter” – im Sinn von “nicht erlaubt” und “du darfst nicht”.
Alles, was daher aufgrund eines Fehlers zum Abbruch führen muss, hat was, so wie du schreibst, mit Exception Handling zu tun. Obiges Beispiel: alles nur kein Grund für die().
Aber vielleicht ist das nur den PHP’lern nicht so recht klar, weil sie die OOP noch nicht so wirklich verinnerlicht haben? ;-)


#002
24. Apr 2009
Frughti

Wie sollte denn, eures Erachtens, Fehlerbehandlung in prozeduraler Programmierung ausschauen?


#003
24. Apr 2009
unset

schau mal auf die im letzten Absatz verlinkte Seite, da steht, wie man es sauber mit trigger_error und einem eigenen error handler machen kann.


#004
24. Apr 2009
PHP-Desaster

Vielleicht sollte man noch kurz erwähnen, dass die() equivalent mit exit ist. Sonderbarerweise findet man für den frühzeitigen Abbruch häufiger die() an.


#005
24. Apr 2009

@PHP-Desaster: “die()” klingt nun mal mächtiger und man gibt dem Skript noch die Chance, seine letzten Worte zu röcheln! ;)


#006
24. Apr 2009
Frughti

Dank dir, an trigger_error hab ich gar nicht mehr gedacht. Schande über mein Haupt *eek*


#007
25. Apr 2009

An einem Punkt komme ich nicht an die(), genauer: exit vorbei: Wenn ich einen HTTP-Cache validiert habe.

Beispiel: Das Objekt HTTP_Response wird erzeugt und prüft, ob die angeforderte Ressource schon beim Client liegt. Wenn nicht, werden einfach normale Header verschickt, und danach können spätere Scripte weiterarbeiten. Wenn doch, wird einfach ein 304 verschickt – und das Script beendet sich und alle übergeordneten Scripte per exit.

Natürlich könnte man hierfür einen Observer setzen, der sich dann separat darum kümmert, ob noch etwas verschickt wird oder nicht. Aber das wäre zuviel Overhead und die Klasse ließe sich weniger flexibel einsetzen.


#008
26. Apr 2009

Huhu,

ich denke ehr, das bei Php nicht so gut die Ausnahmebehandlung in den meisten Büchern ist. Ich habe in den meisten Büchern immer nur ein die() oder echo und dann ein exit gelesen.

Es gibt kaum eine Buch oder Webseite die sich mit try und catch beschäftigt. Man sollte sich von Anfang an damit beschäftigen und ich werde hierzu auch mal ein Artikel verfassen.

Grüße Nico

P.S.: Das ist ein sehr schöner Artikel zu den Thema.

#009
31. Jan 2010

[...] should a PHP skript die? Vor einigen Tagen wurde in einigen Blogs [1][2] diskutiert, ob die Funktion/Sprachkonstrukt die() bzw. exit() sinnvoll ist, wie man sie einsetzen [...]

// kommentieren

// senden
theme von mir, software von wordpress, grid von 960 grid system. funktioniert in allen browsern, aber der safari bekommt das mit der schrift am schönsten hin.