Guma: Debuggen mit error_reporting(E_ALL)

Hallo zusammen, ich will nach Fehlern im PHP-Code suchen. Hier geht es vor allem um Übergabe von Variablen und so weiter. Ich nutze dazu

<?php
error_reporting(E_ALL); ?>

Gibt es weitere Prüfmethoden für PHP-Code? Z.B. für arrays, variablen und so weiter...

Guma

  1. Hallo Guma,

    man kann sich mit print($var); Variable jederzeit anzeigen lassen.
    Das hat mir bislang immer gereicht ...

    Gruss Norbert

    1. Hallo Norbert.

      man kann sich mit print($var); Variable jederzeit anzeigen lassen.

      Außerdem nützlich: print_r(). Und wenn der Datentyp eindeutig erkennbar sein soll var_dump().

      Einen schönen Donnerstag noch.

      Gruß, Ashura

      --
      sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
      mathbr:del.icio.us/ mathbr:w00t/
  2. gudn tach!

    <?php
    error_reporting(E_ALL); ?>

    ja, unter php4.
    unter php5+ empfiehlt sich
      error_reporting(E_ALL | E_STRICT);
    damit auch konstrukte angezeigt werden, die in zukuenftigen php-versionen rausfliegen werden und deswegen ersetzt werden sollten.

    falls du auf einem system arbeitest, bei welchem du nicht weisst, ob php4 oder php5 installiert ist, oder falls der code einfach auf beiden laufen soll, kannst du entsprechend
      error_reporting(E_ALL | (defined('E_STRICT')? E_STRICT : 0));
    benutzen.

    Gibt es weitere Prüfmethoden für PHP-Code? Z.B. für arrays, variablen und so weiter...

    schau dir mal "Example 1. Using error handling in a script" im php-manual an.

    du kannst dann mit [link:http://www.php.net/manual/en/function.trigger-error.php@title=trigger_error] eigene errors/warnings/notices erzeugen und dann in deinem eigenen error-handler sagen, was mit $var (siehe genanntes beispiel) passieren soll.

    print_r ist fuer eine komplette ausgabe am geeignetsten, da die sich selbst referenzierende variable $GLOBALS z.b. der funktion var_export (und iirc auch var_dump) probleme bereitet. andererseits ist fraglich, ob man sich wirklich alle variablen ausgeben lassen will (das sind naemlich viele!).

    prost
    seth

  3. Hallo Guma,

    Hallo zusammen, ich will nach Fehlern im PHP-Code suchen. Hier geht es vor allem um Übergabe von Variablen und so weiter. Ich nutze dazu
    <?php
    error_reporting(E_ALL); ?>

    Gibt es weitere Prüfmethoden für PHP-Code? Z.B. für arrays, variablen und so weiter...

    Das "var_dump" für Einzelvariablen:
    debug_zval_dump()

    Und, um Typen von Variablen zu prüfen:
    gettype()

    Das ist vor allem interessant, wenn man die Rückgabewerte von PHP-internen Funktionen prüfen will. Mir ist es schon passiert, dass eine Funktion entgegen den Angaben im PHP-Manual statt eines Integer-Wertes einen booleschen Wert (»TRUE«) geliefert hat. Mit gettype() kann man das schnell prüfen. Es war übrigens die Funktion error_log() -- und der Fehler steht auch nur in der deutschen Version.

    Und schließlich könnte man auch noch einen richtigen Debugger benutzen. Das soll gegenüber dem Einfügen von print_r()/var_dump() und Co durchaus Vorteile bringen ... ;-)

    MffG
    EisFuX

    --
    ... Suchmaschinen-Blog ...
    1. echo $begrüßung;

      Das "var_dump" für Einzelvariablen:
      debug_zval_dump()

      var_dump funktioniert auch mit "Einzelvariablen" und ist in der Regel völlig ausreichend. Der von debug_zval_dump() zusätzlich ausgegebene Referenzcounter ist in der Regel uninteressant.

      Und, um Typen von Variablen zu prüfen:
      gettype()

      var_dump() zeigt auch den Typ an. Es ist ausreichend, sich var_dump() für alle Lebenslagen zu merken und print_r() zu verwenden, wenn man bei Arrays oder Objekten eine etwas übersichtlichere Ausgabe dafür aber ohne Typinformationen haben möchte.

      [...] eine Funktion [...] statt eines Integer-Wertes einen booleschen Wert (»TRUE«) geliefert hat

      Auch für Ausdrücke und zum Anzeigen von Funktionsergebnissen lässt sich var_dump() sehr gut verwenden.

      echo "$verabschiedung $name";

      1. Hallo dedlfix,

        hmm, ... sollte ich schon wieder was überlesen haben? Ich glaubte, auf diesen Satz des Threaderöffners zu antworten:

        Gibt es weitere Prüfmethoden für PHP-Code? Z.B. für arrays, variablen und so weiter...

        Ich bezog mich also aufs __Prüfen__ und nicht aufs __Anzeigen__ von Variablen-Inhalten oder -Typen ...

        var_dump funktioniert auch mit "Einzelvariablen" und ist in der Regel völlig ausreichend.

        Ist mir bekannt, das tut print_r() übrigens auch.

        Der von debug_zval_dump() zusätzlich ausgegebene Referenzcounter ist in der Regel uninteressant.

        Das interessiert mich unter Umständen durchaus. Auch var_dump() weist bei der Ausgabe von Array-Elementen (laut User-Contributions aber nur dort) dezent mit einem "&" vor dem Variablennamen auf einen Referenz-Counter größer als 1 hin ...

        Und, um Typen von Variablen zu prüfen:
        gettype()
        var_dump() zeigt auch den Typ an.

        Ja aber nicht den Typ alleine. Wenn ich lediglich __prüfen__ will, ob (m)eine Funktion den richtigen Typ zurückliefert, dann interessiert mich der Inhalt der Variablen eher weniger ...

        Auch für Ausdrücke und zum Anzeigen von Funktionsergebnissen lässt sich var_dump() sehr gut verwenden.

        Deine Liebe zu var_dump() in allen Ehren, aber eine Funktion, die ihre Ausgaben lediglich in den Ausgabepuffer schreiben kann, ist als Debugging-Hilfe allein ziemlich ungeeignet -- denn in ein Error-Logfile kann man so (ohne Umwege) nicht schreiben. Bliebe noch die Ausgabe im Browser: Dort produziert es in der HTML-Darstellung Buchstabensalat. print_r() kann seine Ausgabe wenigstens in einen String umleiten.

        Die erste Maßnahme wäre daher, sich eine Wrapper-Funktion zu schreiben, die zumindest das Umleiten der Ausgabe in eine String-Variable erlaubt -- damit man var_dump() auch benutzen kann:

          
        function vdump(  
          $var,  
          $write_to_string = FALSE  
        ) {  
          ob_start();  
          var_dump($var);  
          $out = ob_get_contents();  
          ob_end_clean();  
          
          // für formatierte HTML-Ausgabe:  
          //$out = '<pre>'.preg_replace( array('/&/', '/\</', '/\>/'),array('&#38;', '&#60;', '&#62;'), $out ).'</pre>';  
          
          if(FALSE !== $write_to_string) return($out);  
          
          print($out);  
          return(TRUE);  
        }  
        
        

        Außerdem kann var_dump() nicht wirklich mit zirkulären Referenzen umgehen. Es "erkennt" sie erst im "zweiten Durchgang" und zeigt sie auch nicht an. Das kann, so wie es aussieht, nur print_r() richtig, wie man an der Ausgabe, die folgender Quelltext erzeugt, deutlich sieht:

          
        <?php  
        var_dump($GLOBALS);  
          
        print_r($GLOBALS);  
        ?>  
        
        

        MffG
        EisFuX

        --
        ... Suchmaschinen-Blog ...
        1. Hallo EisFuX.

          // für formatierte HTML-Ausgabe:
            //$out = '<pre>'.preg_replace( array('/&/', '/</', '/>/'),array('&#38;', '&#60;', '&#62;'), $out ).'</pre>';

          Warum das Rad neu erfinden?

          Einen schönen Montag noch.

          Gruß, Ashura

          --
          sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
          mathbr:del.icio.us/ mathbr:w00t/
        2. echo $begrüßung;

          Ich bezog mich also aufs __Prüfen__ und nicht aufs __Anzeigen__ von Variablen-Inhalten oder -Typen ...

          Den Unterschied verstehe ich nicht. Wie prüfst du den Variableninhalt, ohne ihn anzuzeigen?

          [gettype() vs. var_dump()]

          Wenn ich lediglich __prüfen__ will, ob (m)eine Funktion den richtigen Typ zurückliefert, dann interessiert mich der Inhalt der Variablen eher weniger ...

          Ansichtssache. Die zusätzliche Information kann man ja ignorieren. Schwamm drüber.

          Deine Liebe zu var_dump() in allen Ehren, aber eine Funktion, die ihre Ausgaben lediglich in den Ausgabepuffer schreiben kann, ist als Debugging-Hilfe allein ziemlich ungeeignet -- denn in ein Error-Logfile kann man so (ohne Umwege) nicht schreiben.

          Stimmt. Für hartnäckige Fälle, die man in der Testumgebung nicht nachvollziehen kann, also Fehlersuche auf dem Produktivsystem, auf dem die Anwender nichts mitbekommen sollen, ist eine Ausgabe ins Logfile angebrachter. Da hätte ich einen Tipp: trigger_error() plus selbst geschriebener Error-Handler. Damit kann man wunderschön sämtliche Variablen im aktuellen Scope und Backtrace-Ausgaben einbeziehen.

          (Error Handling and Logging Functions)

          Bliebe noch die Ausgabe im Browser: Dort produziert es in der HTML-Darstellung Buchstabensalat. print_r() kann seine Ausgabe wenigstens in einen String umleiten.

          Den Buchstabensalat kann man doch mit Hilfe eines <pre> in eine lesbare Form bringen. :-) (Quelltext-Anzeige wäre auch noch eine Option.)

          Die erste Maßnahme wäre daher, sich eine Wrapper-Funktion zu schreiben, die zumindest das Umleiten der Ausgabe in eine String-Variable erlaubt -- damit man var_dump() auch benutzen kann:

          Meine sieht so aus (auch für PHP < 4.3.0 einsetzbar):

          /**  
           * debug output of $what  
           * @param mixed $what  
           * @param boolean $vardump use var_dump instaed of print_r  
           * @param boolean $noPre don't use <pre> surrounding output  
           * @param boolean $htmlchars convert special html chars to entities  
           * @return void  
           */  
          function Debug($what, $vardump = false, $noPre = false, $htmlchars = false) {  
            echo fDebug($what, $vardump, $noPre, $htmlchars);  
          } //Debug  
            
          /**  
           * returns debug presentation of $what  
           * @param mixed $what  
           * @param boolean $vardump use var_dump instaed of print_r  
           * @param boolean $noPre don't use <pre> surrounding output  
           * @param boolean $htmlchars convert special html chars to entities  
           * @return string  
           */  
          function fDebug($what, $vardump = false, $noPre = false, $htmlchars = false) {  
            ob_start();  
              if ($vardump) {  
                var_dump($what);  
              } else { //if vardump  
                print_r($what);  
              } //else-if vardump  
            $ob = ob_get_contents();  
            ob_end_clean();  
            $result = $htmlchars ? htmlspecialchars($ob) : $ob;  
            if (!$noPre)  
              $result = "<pre>\n$result</pre>\n";  
            
            return $result;  
          } //fDebug
          

          echo "$verabschiedung $name";