Facebook
Twitter
Google+
Kommentare
16

Debug Ausgaben

PHP ist dafür bekannt, das man gerne die Möglichkeiten eines Debuggers vergisst und das altbewährte var_dump oder echo verwendet, um rauszufinden, welchen Status einzelne Variablen gerade haben. Ich muss ja gestehen, dass ich auch gerne echo verwende und ich eigentlich relativ zufrieden damit bin. Nur leider vergisst man ab und zu doch mal den ein oder anderen Debug-Output und dieser findet sich dann in der Versionsverwaltung wieder. Meistens findet man es noch bevor es live geht, trotzdem ist es unschön und fehleranfällig. Wie kann man das aber verhindern?

Eigentlich ganz einfach. Benutzt eine kleine Hilfsfunktion. Schreibt euch eine Methode, die debugEcho heißt (gilt natürlich auch für debugVarDump). Diese sieht wie folgt aus:

function debugEcho( $string )
{
  echo $string;
}

So jetzt werdet ihr erstmal denken, dass diese Methode ja sowas von unnötig ist, da sie einfach nur den Befehl weiter reicht und nichts anderes macht. Und was soll ich sagen? Stimmt! Was soll dieser Ansatz denn dann? Ok wir machen zwar nichts anderes als der echo Befehl auch, nur wir können jetzt unterscheiden, was ein normales echo ist und was als debug Output gedacht ist. Ab jetzt können wir ohne Probleme ein kleines Werkzeug schreiben, dass unerwünschte Ausgaben findet. Integriert in ein SVN Prehook könnte man zum Beispiel verhindern, dass die Entwickler solchen Code überhaupt einchecken können. Aber wenn man keine Hooks anwenden möchte, dann sollte man sein PHPUnderControl verwenden um sie zu finden.

Über den Autor

Nils Langner

Nils Langner ist der Gründer von "the web hates me" und auch der Hauptautor. Im wahren Leben leitet er das Qualitätsmanagementteam im Gruner+Jahr-Digitalbereich und ist somit für Seiten wie stern.de, eltern.de und gala.de aus Qualitätssicht verantwortlich. Nils schreibt seit den Anfängen von phphatesme, welches er ebenfalls gegründet hat, nicht nur für diverse Blogs, sondern auch für Fachmagazine, wie das PHP Magazin, die t3n, die c't oder die iX. Nebenbei ist er noch ein gern gesehener Sprecher auf Konferenzen. Herr Langner schreibt die Texte über sich gerne in der dritten Form.
Kommentare

16 Comments

  1. Netter Ansatz, jedoch sehe ich da noch mehr Vorteile, die so nicht erwähnt wurden, beim Lesen jedoch hervor kamen. Wenn man das Projekt live schaltet, kann mana uch ganz einfach die echo Ausgabe auskommentieren und schon gibt es nirgens mehr eine ungewollte Ausgabe und auch keinen Fehlerwurf. Das Ganze kann man natürlich noch weiter spinnen und etwas automatisieren, aber es ist auch eine nette Idee. Ich selber nutze vom Ansatz her eine Ähnliche Funktion bereits einige Jahre und sie vereinfacht obendrein die Arbeit allgemein 🙂

    Reply
  2. Oder einfach vor Live-Schaltung die Funktion abändern:

    function debugEcho( $string )
    {
    echo “; // $string;
    }

    Reply
  3. Entweder die Daten sind wirklich unwichtig und man sollte schauen das man die Ausgaben los wird, oder man sollte sich überlegen die Daten in ein Log-file zu schreiben.

    Reply
  4. Ich benutze für’s Debugging oft error_log() – hat den Vorteil, dass es die HTML-Seite nicht verunstaltet, schön in PHPs error_log-Datei zu lesen ist und nicht so weh tut, wenn man’s aus Versehen eincheckt.

    Reply
  5. Wirf doch mal ein Block auf FirePHP 😉
    1. zerstören Debug-Ausgaben nicht das Design
    2. kann man den ganz einfach deaktivieren (zumindest die Zend_Log_Adapter_Firebug Version)

    Reply
  6. debugEcho() halte ich auch für recht kompliziert. Erstens vergisst man vielleicht aus Gewohnheit, diese Funktion zu nutzen, zweitens würde ich in diese Funktion, falls ich sie nutzen würde, eine Abfrage reinbauen wie

    if (APPLICATION_ENV == ‚DEVELOPEMENT‘)
    echo $string;

    sodass die Debug-Ausgaben auch garantiert nur auf den Entwicklungsmaschinen ausgegeben wird.

    Wir nutzen hier derzeit auch FirePHP (bzw. den Zend_Log Firebug writer)

    Reply
  7. Scheint ja ein kommunikationsfreudiges Thema zu sein. Grunsätzlich sind natürlich alle Ansätze gut, keine Frage. Mir geht es nur drum einen Weg zu finden, wie man es schafft diese fiesen „echoes“ aus dem Code rauszubekommen. Und da ich ein großer Freund des Contionuos Integration Ansatzes bin, habe ich natürlich diesen gewählt.

    Reply
  8. Man koennte sich eine config.php anlegen, die auf svn-ignore (falls man svn nutzt) steht und wo drin vermerkt ist, ob man sich gerade im Debug-Mode befindet. Dann braeuchte man nur noch in der debugEcho-Funktion eine IF-Abfrage .

    function debugEcho($str) > if(defined(‚DEBUG‘) && DEBUG) > echo $str;

    In der Produktivumgebung ist dann ne andere config.php in Verwendung. Idealer Weise hat man dann immer noch eine config.sample im Verzeichnis mit rumliegen, welche dann in der Versionskontrolle mit bedacht ist

    Reply
  9. @rkr: würde gehen, ist aber eine unschöne Sache. Ich zB möchte immer gern alles ins SVN packen.

    Wir machen es derzeit nach diesem Schema:
    http://www.ajaxray.com/blog/2009/02/03/advanced-bootstrapping-configure-your-zend-framework-application-for-multiple-host/

    Sprich: Wir stellen in der bootstrap-Datei fest, ob wir uns auf einem Entwicklungsrechner oder Produktivrechner befinden (anhang der Url oder Rechnername oder sowas). Dies wird im Beispiel oben „APPSTAGE“ genannt. Dann wird die config geladen, und je nach Stage dann der richtige Teil dieser config. Das geht auch mit .ini Dateien (mit Hilfe von Sektionen). Einfach mal googlen.

    Dann hat man nur 1 config im svn, und alle Entwickler können normal arbeiten. Bei deinem Beispiel wäre es zB problematisch, falls in die config ein weiterer Wert dazukäme. Dann müßten alle Entwickler lokal in ihren devel-configs rumeditieren.

    In der Config (in der Produktiv-Sektion) würde man dann einfach „Debug = 0“ setzen, und in der Developer-Sektion dann „Debug = 1“.

    Reply
  10. Sehr gute Idee, ich glaube das ist jedem schon mal passiert. Meinst merkt man es ja recht schnell, direkt nachdem der Commit gelaufen ist 🙂

    Ansonsten kann ich nur die Variante mit dem Logfile und der separaten Konfigurationsdatei mit svn:ignore empfehlen.

    Reply
  11. @Michael: Das Problem ist, dass nicht ueberall mit HTTP_HOST gearbeitet werden kann. Wenn man zum Teil die Konsole nutzt oder auf cronjob-Ebene Dinge ausfuehrt, dann muss man sich die Hostinformationen von Woanders holen.

    Ausreichend waere, wenn man nicht die ganze Konfigurations-Datei dafuer nutzt. Eine seperate Datei, wo man drin festhaelt, in welcher Umgebung man sich gerade befindet, wuerde es auch tun.

    Reply
  12. Das stimmt natürlich. Aber dafür schrieb ich ja, kann man den Rechnernamen nehmen oder zB eine Environment-Variable setzen.
    Oder wie du schon sagtest, eine kleine Datei, wo nur drinsteht, ob Development oder Production. Falls man auf einem Rechner sowohl Dev als auch Prod installieren will, nimmt man noch zusätzlich den Pfad als Entscheidungskriterium.

    Wenn es geht, vermeide ich aber solche Dateien, die nicht ins svn geladen werden, denn das sind potentielle Fehlerquellen. Das erneute Ausrollen auf neuen Rechnern (zB weil einer ausgefallen ist) kann dann auch von unbedarften Leuten gemacht werden, weil man einfach nur den svn-checkout machen muß, und wenig/keine zusätzlichen Dinge beachten muss.

    Reply
  13. @Michael: Ist die Verwendung des Hostnamens oder einer ganz bestimmten Enviroment-Variablen nicht mindestens genauso fehleranfällig wie die Verwendung eines Konfigurationsfiles? Wenn diese Requirements nicht oder nur unzureichend dokumentiert sind wird jemand Unbedarftes wahrscheinlich deutlich mehr Schwierigkeiten mit dem Einrichten haben als jemand der ein Konfigurationsfile bearbeiten muss.

    Ich kenne beide Varianten aus Projekten und denke nicht dass sich beides viel nimmt. Wie so oft eine Frage des persönlichen Geschmacks.

    Reply
  14. error_log verhindert die Anzeige im Code. Überall. FirePHP mag ich nicht. Was bleibt mir? Wofür hab ich 2 Monitore? 😀
    tail /var/log/php5/* -f 😉

    Reply
  15. Ich find die Idee nicht verkehrt. Ist quick’n’dirty. Könnt man vll noch zur Spitze treiben, statt des simplen echos erstmal in ein Array speichern und am Ende des Scripts über nen Aufruf der Funkion ausgeben. Verhindert auch, dasses zu unerwünschten Nebeneffekten kommt, wenn ne Echoausgabe (versehentlich) vor einer Header-Ausgabe stattfindet.

    Reply

Leave a Comment.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen