Ankündigung

Einklappen
Keine Ankündigung bisher.

Debugging

Einklappen
Dieses Thema ist geschlossen.
X
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Debugging

    Hallo,
    ich möchte das Tutorial gern um einige hilfreiche Skripte erweitern und dazu meine kleine Klasse "Debug" vorstellen.

    Ich verwende sie täglich beim Coden (blöder Werbespruch, aber ist einfach so). Was mir bei normalen echo/print Ausgaben zu Debug-Zwecken immer gefehlt hat, war
    a.) ein extra "exit", der das Skript beendet hat
    b.) eine Typ-genaue Ausgabe, also (bool)false oder (int)1 o.ä.
    c.) woher das echo-Debug aufgerufen wurde

    Ich habe versucht, diese 3 Eigenschaften in meine Klasse einzubauen und es ist zu meiner Zufriedenheit gelungen. War ja auch nicht schwer

    Ein
    PHP-Code:
    <?php
    echo '<pre>'print_r($aArraytrue), '</pre>'; exit;
    ?>
    war eben nicht so schnell hingeschrieben, wie
    PHP-Code:
    <?php
    Debug
    ::stop($aArray);
    ?>
    Zur Verfügung stehen die statischen Methoden write() und stop().
    Ihnen können beliebig viele Parameter beliebiger Variablen-Typen übergeben werden. Sie unterscheiden sich lediglich darin, dass stop() das Skript beim Aufruf abbricht (exit).

    Eine Debug-Ausgabe könnte also so aussehen:
    Code:
    DEBUG ARG-0
    string(7) "install"
    
    
    DEBUG ARG-1
    string(12) "#^[\w\d_]+$#"
    
    
    DEBUG BACKTRACE
    Array
    (
        [0] => J:\Server\common\php5\classes\Validate.php:12
        [1] => J:\Server\projects\local_newsletteradmin\htdocs\index.php:31
    )
    
    
    DEBUG MESSAGE
    script stopped
    Der Abschnitt DEBUG BACKTRACE gibt -den Aufruf rückverfolgend- zusätzlich noch die verursachenden Code-Zeilen an.

    Die Ausgabe erfolgt über die private statische Methode output().
    Hier könnte also eine Debug-Konstante eingefügt werden und während dem Live-Modus Debug-Ausgaben unterbinden.

    Hier die Klasse (PHP4 und PHP5 tauglich):
    PHP-Code:
    <?php
    ////////////////////////////////////////////////////////////////////////////////////////////////////

    class Debug
    {
        
    ////////////////////////////////////////////////////////////////////////////////////////////////
        // public static functions
        
        /* public static */ 
    function write()
        {
            
    $aArgv func_get_args();
            for (
    $i 0$iCount count($aArgv); $i $iCount$i++) {
                echo 
    Debug::output($aArgv[$i], "ARG-$i");
            } 
            echo 
    Debug::backtrace();       
        }
        
        
    /* public static */ function stop()
        {
            
    $aArgv func_get_args();
            for (
    $i 0$iCount count($aArgv); $i $iCount$i++) {
                echo 
    Debug::output($aArgv[$i], "ARG-$i");
            }
            echo 
    Debug::backtrace();
            echo 
    Debug::output('script stopped''MESSAGE'false);
            exit;
        }
        
        
        
    ////////////////////////////////////////////////////////////////////////////////////////////////
        // private static functions
        
        /* private static */ 
    function output($mVariable$sTitle ''$bShowType true)
        {
            if (
    $bShowType) {
                
    ob_start();
                
    var_dump($mVariable);
                
    $sContents ob_get_contents();
                
    ob_end_clean();
            } else {
                
    $sContents print_r($mVariabletrue);
            } 
            return 
    sprintf("<pre>DEBUG %s\n%s\n</pre>"strtoupper($sTitle), $sContents);
        }
        
        
    /* private static */ function backtrace()
        {
            
    $aBacktrace debug_backtrace();
            
    $aReturn = array();
            for (
    $i 1$iCount count($aBacktrace); $i $iCount$i++) {
                
    $aReturn[] = sprintf('%s:%u'$aBacktrace[$i]['file'], $aBacktrace[$i]['line']);
            }
            if (
    count($aReturn) == 0) {
                return 
    '';
            }
            
            return 
    Debug::output($aReturn"BACKTRACE"false);
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////
    ?>


  • #2
    Ne runde Sache. Sehr schön.
    --

    „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
    Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


    --

    Kommentar


    • #3
      Es wird noch runder, leider schon fast etwas überladen. Aber ich habe die Klasse etwas erweitert - sono hier ausm Forum hat mich da etwas inspiriert, danke dafür gleich an dieser Stelle - und zwar um die Methoden report und table.

      Mittels report lassen sich die Superglobalen (GET, POST, COOKIE, SESSION, SERVER, ENV, FILES, GLOBALS) tabellarisch ausgeben.
      Dazu kann report entweder ohne Argumente aufgerufen werden oder als Argument 1 mit einem String, der die Abkürzungen für die Superglobalen enthält.

      PHP-Code:
      <?php
      Debug
      ::report('SEPEG');
      ?>
      Dieser Code würde also in der festgelegten Reihenfolge Session, Post, Env und Get ausgeben. Ähnlich also dem php.ini-Flag "variables_order".

      Die Methode table gibt einen Array als Tabelle aus. Fährt man über die <tr>-Zeile zeigt das title-Attribut die Array-Keys an, die benötigt werden um an den Wert unter der Maus zu kommen.

      Als nächste Erweiterung ist eine Unterklasse geplant, die die Debug-Ausgaben zusätzlich oder je nach Fehler-Level in ein Log-File schreibt anstatt sie auszugeben.

      PHP-Code:
      <?php
      /**
       * @author  Christian Reinecke <christian.reinecke@web.de>
       * @date    2007-07-23
       *
       * little helper for debug output
       * the methods are all static, there is no static declaration just because of downward compatibility
       * use only the public static methods
       * all methods starting with an underscore like _display() are for internal static use only - do not use them
       *
       * @example:
       * Debug::on(); // optional
       * Debug::write(new stdClass, array(1,2), 5, 6.0, 'seven', null, false);
       * Debug::write("hallo", "hello", "salut");
       * Debug::off();
       * Debug::write("you'll never see that output");
       * Debug::on();
       * Debug::table(array('one' => 'two', 'three' => 'four', 'five' => array('six')));
       * Debug::report('SEEG'); // puts out the Arays SE(ssion), E(nv) and G(et) in this order
       *
       * thanks to Dominik Bonsch <info@web-modules.de> for some code snippets and inspiration (report/table)
       */
      class Debug
      {
          
      /**
           * reactivate debug output (default is on)
           * @access   public
           * @return   void
           * @example  Debug::on()
           */
          
      function on()
          {
              unset(
      $GLOBALS['DEBUG_CLASS_OFF']);
          }

          
      /**
           * deactivate debug output
           * @access   public
           * @return   void
           * @example  Debug::off()
           */
          
      function off()
          {
              
      $GLOBALS['DEBUG_CLASS_OFF'] = true;
          }

          
      /**
           * puts some given variables out
           * @access   public
           * @return   void
           * @example  Debug::write($myArray, $myInteger, $mObject, $myString, ..);
           */
          
      function write(/** $var1, $var2, .. **/)
          {
              
      $aArgv func_get_args();
              for (
      $i 0$k 1$x count($aArgv); $i $x; ++$i, ++$k) {
                  
      $aOutput[] = Debug::_var($aArgv[$i], "ARG $k");
              }
              
      $aOutput[] = Debug::_backtrace();
              
      Debug::_display($aOutput);
          }

          
      /**
           * puts some given variables out and stops afterwards
           * @access   public
           * @return   void
           * @example  Debug::stop($myArray, $myInteger, $mObject, $myString, ..);
           */
          
      function stop(/** $var1, $var2, .. **/)
          {
              
      $aOutput = array();
              
      $aArgv func_get_args();
              for (
      $i 0$k 1$x count($aArgv); $i $x; ++$i, ++$k) {
                  
      $aOutput[] = Debug::_var($aArgv[$i], "ARG $k");
              }
              
      $aOutput[] = Debug::_backtrace();
              
      Debug::_display($aOutputtrue);
          }

          
      /**
           * puts the content of the superglobals $_GET, $_POST, $_COOKIE, $_SESSION, $_SERVER, $_ENV and $_FILES out.
           * @param    string   $sSuperGlobals  list of char shortcuts to order the output, default available
           * @param    boolean  $bExit          exit afterwards
           * @return   void
           * @example  Debug::report('GPF', 1);
           */
          
      function report($sSuperGlobals 'GPCSESVEF'$bExit false)
          {
              
      $aSuperGlobals = array('G'  => array('GET',     $_GET),
                                     
      'P'  => array('POST',    $_POST),
                                     
      'C'  => array('COOKIE',  $_COOKIE),
                                     
      'SE' => array('SESSION'$_SESSION),
                                     
      'SV' => array('SERVER',  $_SERVER),
                                     
      'E'  => array('ENV',     $_ENV),
                                     
      'F'  => array('FILES',   $_FILES,
                                     
      'GL' => array('GLOBALS'$GLOBALS)));
              
      $sSuperGlobals strtoupper($sSuperGlobals);
              
      $aOutput = array();
              foreach (
      $aSuperGlobals as $sChar => $aSuperGlobal) {
                  if ((
      $iPos strpos($sSuperGlobals$sChar)) !== false) {
                      
      $sSuperGlobals substr($sSuperGlobals0$iPos) . str_pad(''strlen($sChar), ' ') . substr($sSuperGlobals$iPos strlen($sChar));
                      
      $aOutput[$iPos 0] = Debug::_msg($aSuperGlobal[0]);
                      
      $aOutput[$iPos 1] = Debug::table($aSuperGlobal[1], false);
                  }
              }
              if (
      count($aOutput) == 0) {
                  
      trigger_error('Debug::report(): Argument #1 should be a string containing at least one of the following char combinations: ' .
                                
      implode(', 'array_keys($aSuperGlobals)),
                                
      E_USER_NOTICE);
                  return 
      null;
              }
              
      ksort($aOutput);
              
      $aOutput[] = Debug::_backtrace();
              
      Debug::_display($aOutput$bExit);
          }

          
      /**
           * puts the content of an array out
           * @access   public
           * @param    array    $aArray
           * @param    boolean  $bPrint     print, othervise return (set automatically on recursion)
           * @param    string   $sPreTitle  title attribute for cells (set automatically on recursion)
           * @param    integer  $iDepth     recursion depth (used to detect recursion)
           * @return   mixed    depends on $bPrint
           * @example  Debug::table($_SESSION); this is by the same: Debug::report('SE')
           */
          
      function table($aArray$bPrint true$sPreTitle ''$iDepth 0)
          {
              
      $aOutput = array();
              if (
      $iDepth == 0) {
                  
      $aOutput[] = Debug::_msg('TABLE');
              }
              
      $aOutput[] = '<pre class="debug_class"><table border="1" cellspacing="0" class="debug_class">';
              if (!
      is_array($aArray)) {
                  
      $aOutput[] = sprintf("<tr><th>[i]%s[/i]</td></tr>"strtoupper(gettype($aArray)));
              } else if (
      count($aArray) == 0) {
                  
      $aOutput[] = '<tr><th>[i]EMPTY[/i]</td></tr>';
              } else {
                  foreach (
      $aArray as $sKey => $mValue) {
                      
      $sCurrentTitle "{$sPreTitle}[{$sKey}]";
                      if (
      is_array($mValue)) {
                          
      $sContent Debug::table($mValuefalse$sCurrentTitle$iDepth 1);
                      } else {
                          
      ob_start();
                          
      var_dump($mValue);
                          
      $sContent ob_get_contents();
                          
      ob_end_clean();
                      }
                      
      $aOutput[] = sprintf('<tr title="%s"><th>%s</th><td>%s</td></tr>'$sCurrentTitle$sKey$sContent);
                  }
              }
              
      $aOutput[] = '</table></pre>';
              if (!
      $bPrint) {
                  return 
      implode("\n"$aOutput);
              } else {
                  
      $aOutput[] = Debug::_backtrace();
                  
      Debug::_display($aOutput);
              }
          }

          
      /**
           * all output runs over this method to centralize on/off switch
           * @access  private
           */
          
      function _display($aOutput$bExit false)
          {
              if (!
      is_array($aOutput)) {
                  
      trigger_error('Debug::_display(): Argument #1 should be an array'E_USER_WARNING);
                  return 
      null;
              }

              if (
      $bExit) {
                  
      $aOutput[] = '';
                  
      $aOutput[] = Debug::_msg('STOP');
              }
              if (!isset(
      $GLOBALS['DEBUG_CLASS_OFF']) || $GLOBALS['DEBUG_CLASS_OFF'] === false) {
                  print 
      '<pre class="debug">' implode("\n"$aOutput) .'</pre>';
                  if (
      $bExit) {
                      exit;
                  }
              }
          }

          
      /**
           * @access  private
           */
          
      function _msg($sMsg null)
          {
              if (isset(
      $sMsg)) {
                  return 
      'DEBUG ' strtoupper($sMsg);
              } else {
                  return 
      '';
              }
          }

          
      /**
           * @access  private
           */
          
      function _var($mVariable$sMsg ''$bShowType true)
          {
              
      ob_start();
              if (!empty(
      $sMsg)) {
                  print 
      Debug::_msg($sMsg);
                  print 
      "\n";
              }
              if (
      $bShowType) {
                  
      var_dump($mVariable);
              } else {
                  
      // second argument is supported since 4.3, let's fix it with output buffering
                  
      print_r($mVariable);
              }
              
      $sOutput ob_get_contents();
              
      ob_end_clean();
              return 
      $sOutput;
          }

          
      /**
           * @access   private
           * @warning  do not use the debug_backtrace*() functions as parameter for any method of this class
           *           othervise it might end in an infinite loop
           */
          
      function _backtrace()
          {
              
      $aBacktrace debug_backtrace();
              
      $aOutput = array(Debug::_msg('BACKTRACE'));
              for (
      $i 1$x count($aBacktrace); $i $x; ++$i) {
                  
      $aOutput[] = sprintf('[%u] %s:%u'$x $i$aBacktrace[$i]['file'], $aBacktrace[$i]['line']);
              }
              if (
      count($aOutput) == 0) {
                  return 
      '';
              }
              return 
      implode("\n"$aOutput);
          }
      }
      ?>

      Kommentar


      • #4
        Die nächste Erweiterung sind die Debug::argument() und Debug::arguments() Methoden, mit denen sich Argumente/Parameter einer fremden Funktion oder Methode testen lassen. Man entschuldige die wieder mal gewechselte Variablenschreibweise meinerseits.

        PHP-Code:
        <?php
        function myFunc($integer$string$objectStdClass$array)
        {
          
        System::arguments(func_get_args(), array('integer''string''object(stdclass)''array(key1,key2)'));
          
        // ..
        }
        ?>
        Werden der Funktion myFunc nun (in dieser Reihenfolge) nicht ein Integer, String, ein stdClass-Objekt oder Array mit den Schlüsseln key1 und key2 übergeben, löst ein trigger_error() einen Notice aus. Natürlich nur wenn Debugging aktiviert ist.

        Mögliche Einstellung sind alle gettype() Rückgabewerte, bei Arrays zusätzlich
        Code:
        array(N); // N = Anzahl der Elemente
        array(N,i); // i steht für die Eigenschaft, dass das Array bei 0 beginnende fortlaufende Indexe hat (also für for() geeignet ist)
        array(X,Y,Z); // X, Y und Z stehten für Schlüssel, die in diesem Array vorhanden sein müssen, alphabetische Reihenfolge vorausgesetzt
        Objekte mittels
        Code:
        object(C); // C = Klassen-Name
        Hinzukommen wird demnächst noch die Prüfung auf einen Array deren Elemente Objekte einer Klasse sind, in etwa
        Code:
        array(object(stdclass))
        Ich weiß dass PHP 5 bereits eine implementierte Syntax für Objekte als Parameter anbietet, nichtsdestotrotz benötigte ich das ganze für alle Variablen-Typen und auch für PHP 4.

        Ich brauche recht häufig den Check auf Argumente, zugegebenermaßen kann man flexibler sein, wenn man sich das ganze fix ausschreibt, allerdings hat sich dabei doch sehr viel Code wiederholt. Das wollte ich hierdurch vermeiden.

        Da es weiterhin den Debug:ff() Aufruf gibt bzw. man das Error-Level für Produktiv-Umgebungen ja sowieso hochstellt, finde ich das ganze sehr angenehm.

        PHP-Code:
        <?php
        /**
         * @author  Christian Reinecke <christian.reinecke@web.de>
         * @date    2007-05-16
         *
         * little helper for debug output
         * the methods are all static, there is no static declaration just because of downward compatibility
         * use only the public static methods
         * all methods starting with an underscore like _display() are for internal static use only - do not use them
         */

        /**
         * defines the name of the global variable used to save the state of the debug mode (on|off)
         * if you have any conflicts in your namespace with this name, change it here
         */
        define('DEBUG_GLOBAL_VAR''__DEBUG_ON');
        ${
        DEBUG_GLOBAL_VAR} = true;


        /**
         * defines the error message and warning level for a bad argument
         */
        define('DEBUG_ERROR_ARGUMENT''%s(): Argument#%u (%s) should be of type %s in [b]%s[/b] on line [b]%u[/b], triggered actually');
        define('DEBUG_ERRNO_ARGUMENT'E_USER_NOTICE);

        class 
        Debug
        {
            
        /**
             * @example
             * Debug::on(); // optional
             * Debug::write(new stdClass, array(1,2), 5, 6.0, 'seven', null, false);
             * Debug::write("hallo", "hello", "salut");
             * Debug::off();
             * Debug::write("you'll never see that output");
             * Debug::on();
             * Debug::table(array('one' => 'two', 'three' => 'four', 'five' => array('six')));
             * Debug::report('SEEG'); // puts out the Arays SE(ssion), E(nv) and G(et) in this order
             *
             * thanks to Dominik Bonsch <info@web-modules.de> for some code snippets and inspiration (report/table)
             *
             * you can also check arguments
             * @example
             * Debug::on(); // optional
             * function MyFunction($integer) {
             *   System::argument($integer, 'integer');
             *   // ..
             * }
             * // in case that $integer is not an integer a warning is triggered ({DEBUG_ERRNO_ARGUMENT})
             * class MyClass {
             *   function myMethod($object, $array1, $array2, $string) {
             *     System::arguments(func_get_args(), array('object(stdClass)', 'array(key1,key2)', 'array(2)', 'string'));
             *     // ..
             *   }
             *   // same procedure
             * }
             */

             /**
             * reactivate debug output (default is on)
             * @access   public
             * @return   void
             * @example  Debug::on()
             */
            
        function on()
            {
                
        $GLOBALS[DEBUG_GLOBAL_VAR] = true;
            }

            
        /**
             * deactivate debug output
             * @access   public
             * @return   void
             * @example  Debug::off()
             */
            
        function off()
            {
                
        $GLOBALS[DEBUG_GLOBAL_VAR] = false;
            }

            
        /**
             * puts some given variables out
             * @access   public
             * @return   void
             * @example  Debug::write($myArray, $myInteger, $mObject, $myString, ..);
             */
            
        function write(/** $var1, $var2, .. **/)
            {
                if (!
        $GLOBALS[DEBUG_GLOBAL_VAR]) {
                    return;
                }
                
        $aArgv func_get_args();
                for (
        $i 0$k 1$x count($aArgv); $i $x; ++$i, ++$k) {
                    
        $aOutput[] = Debug::_var($aArgv[$i], "ARG $k");
                }
                
        $aOutput[] = Debug::_backtrace();
                
        Debug::_display($aOutput);
            }

            
        /**
             * puts some given variables out and stops afterwards
             * @access   public
             * @return   void
             * @example  Debug::stop($myArray, $myInteger, $mObject, $myString, ..);
             */
            
        function stop(/** $var1, $var2, .. **/)
            {
                if (!
        $GLOBALS[DEBUG_GLOBAL_VAR]) {
                    return;
                }
                
        $aOutput = array();
                
        $aArgv func_get_args();
                for (
        $i 0$k 1$x count($aArgv); $i $x; ++$i, ++$k) {
                    
        $aOutput[] = Debug::_var($aArgv[$i], "ARG $k");
                }
                
        $aOutput[] = Debug::_backtrace();
                
        Debug::_display($aOutputtrue);
            }

            
        /**
             * puts the content of the superglobals $_GET, $_POST, $_COOKIE, $_SESSION, $_SERVER, $_ENV and $_FILES out.
             * @param    string   $sSuperGlobals  list of char shortcuts to order the output, default available
             * @param    boolean  $bExit          exit afterwards
             * @return   void
             * @example  Debug::report('GPF', 1);
             */
            
        function report($sSuperGlobals 'GPCSESVEF'$bExit false)
            {
                if (!
        $GLOBALS[DEBUG_GLOBAL_VAR]) {
                    return;
                }
                
        $aSuperGlobals = array('G'  => array('GET',     $_GET),
                                       
        'P'  => array('POST',    $_POST),
                                       
        'C'  => array('COOKIE',  $_COOKIE),
                                       
        'SE' => array('SESSION'$_SESSION),
                                       
        'SV' => array('SERVER',  $_SERVER),
                                       
        'E'  => array('ENV',     $_ENV),
                                       
        'F'  => array('FILES',   $_FILES,
                                       
        'GL' => array('GLOBALS'$GLOBALS)));
                
        $sSuperGlobals strtoupper($sSuperGlobals);
                
        $aOutput = array();
                foreach (
        $aSuperGlobals as $sChar => $aSuperGlobal) {
                    if ((
        $iPos strpos($sSuperGlobals$sChar)) !== false) {
                        
        #var_dump("vorher $sSuperGlobals");
                        
        $sSuperGlobals substr($sSuperGlobals0$iPos) . str_pad(''strlen($sChar), ' ') . substr($sSuperGlobals$iPos strlen($sChar));
                        
        #var_dump("nachher $sSuperGlobals");
                        #var_dump($iPos * 2);

                        
        $aOutput[$iPos 0] = Debug::_msg($aSuperGlobal[0]);
                        
        $aOutput[$iPos 1] = Debug::table($aSuperGlobal[1], false);
                    }
                }
                if (
        count($aOutput) == 0) {
                    
        trigger_error('Debug::report(): Argument #1 should be a string containing at least one of the following char combinations: ' .
                                  
        implode(', 'array_keys($aSuperGlobals)),
                                  
        E_USER_NOTICE);
                    return 
        null;
                }
                
        ksort($aOutput);
                
        #$aOutput = array_merge($aOutput);
                
        $aOutput[] = Debug::_backtrace();
                
        Debug::_display($aOutput$bExit);
            }

            
        /**
             * puts the content of an array out
             * @access   public
             * @param    array    $aArray
             * @param    boolean  $bPrint     print, othervise return (set automatically on recursion)
             * @param    string   $sPreTitle  title attribute for cells (set automatically on recursion)
             * @param    integer  $iDepth     recursion depth (used to detect recursion)
             * @return   mixed    depends on $bPrint
             * @example  Debug::table($_SESSION); this is by the same: Debug::report('SE')
             */
            
        function table($aArray$bPrint true$sPreTitle ''$iDepth 0)
            {
                if (!
        $GLOBALS[DEBUG_GLOBAL_VAR]) {
                    return;
                }
                
        $aOutput = array();
                if (
        $iDepth == 0) {
                    
        $aOutput[] = Debug::_msg('TABLE');
                }
                
        $aOutput[] = '<pre class="debug_class"><table border="1" cellspacing="0" class="debug_class">';
                if (!
        is_array($aArray)) {
                    
        $aOutput[] = sprintf("<tr><th>[i]%s[/i]</td></tr>"strtoupper(gettype($aArray)));
                } else if (
        count($aArray) == 0) {
                    
        $aOutput[] = '<tr><th>[i]EMPTY[/i]</td></tr>';
                } else {
                    foreach (
        $aArray as $sKey => $mValue) {
                        
        $sCurrentTitle "{$sPreTitle}[{$sKey}]";
                        if (
        is_array($mValue)) {
                            
        $sContent Debug::table($mValuefalse$sCurrentTitle$iDepth 1);
                        } else {
                            
        ob_start();
                            
        var_dump($mValue);
                            
        $sContent ob_get_contents();
                            
        ob_end_clean();
                        }
                        
        $aOutput[] = sprintf('<tr title="%s"><th>%s</th><td>%s</td></tr>'$sCurrentTitle$sKey$sContent);
                    }
                }
                
        $aOutput[] = '</table></pre>';
                if (!
        $bPrint) {
                    return 
        implode("\n"$aOutput);
                } else {
                    
        $aOutput[] = Debug::_backtrace();
                    
        Debug::_display($aOutput);
                }
            }

            
        /**
             * checks whether the given argument has the expected type
             *
             * @static
             * @access public
             * @param mixed $argument argument to check
             * @param string $expected expected type of the argument
             * @param integer $argumentNumber argument number
             * @param integer $additionalBacksteps increase once for every function/method calling
             *                                     {Debug::argument()} not directly for use (f.e.
             *                                     {Debug::arguments()})
             * @return boolean argument matches the expected type
             */
            
        function argument($arg$expected$argumentNumber 1$steps 0)
            {
                if (!
        $GLOBALS[DEBUG_GLOBAL_VAR]) {
                    return;
                }
                if (
        is_null($arg)) {
                    return 
        true;
                }
                
        $is Debug::_analyseArgument($arg);
                
        /**
                 * this is a case-insensitive check, limiting the compare to the
                 * length of the expected string value, making it possible to compare for the type only
                 * although using the more complex return type of {Debug::analyse()}
                 * @example
                 * strncasecmp($is = 'object(stdclass)', $expected = 'object')           -> TRUE
                 * strncasecmp($is = 'object(stdclass)', $expected = 'object(stdclass)') -> TRUE (sure)
                 * strncasecmp($is = 'object(stdclass)', $expected = 'Object(stdClass)') -> TRUE
                 * strncasecmp($is = 'array(2,i)',       $expected = 'array(2)')         -> TRUE
                 * strncasecmp($is = 'array(2)',         $expected = 'array(3)')         -> FALSE (sure)
                 * etc.
                 * */
                
        if (strncasecmp($is$expectedstrlen($expected) - 1) != 0) {
                    
        Debug::_triggerArgument($argumentNumber$is$expected$steps);
                    return 
        false;
                }
                return 
        true;
            }

            
        /**
             * checks multiple arguments
             *
             * @static
             * @access public
             * @param array $argv array of arguments
             * @param array $argvExpected array of the expected types
             * @return boolean all arguments passed the check
             */
            
        function arguments($argv$argvExpected)
            {
                if (!
        $GLOBALS[DEBUG_GLOBAL_VAR]) {
                    return;
                }
                for (
        $i 0$x min(count($argv), count($argvExpected)); $i $x; ++$i) {
                    if (!
        Debug::argument($argv[$i], $argvExpected[$i], $i 11)) {
                        return 
        false;
                    }
                }
                return 
        true;
            }

            
        /**
             * display
             * @access  private
             */
            
        function _display($aOutput$bExit false)
            {
                
        Debug::argument($aOutput'array');

                if (
        $bExit) {
                    
        $aOutput[] = '';
                    
        $aOutput[] = Debug::_msg('STOP');
                }
                print 
        '<pre class="debug">' implode("\n"$aOutput) .'</pre>';
                if (
        $bExit) {
                    exit;
                }
            }

            
        /**
             * @access  private
             */
            
        function _msg($sMsg null)
            {
                if (isset(
        $sMsg)) {
                    return 
        'DEBUG ' strtoupper($sMsg);
                } else {
                    return 
        '';
                }
            }

            
        /**
             * @access  private
             */
            
        function _var($mVariable$sMsg ''$bShowType true)
            {
                
        ob_start();
                if (!empty(
        $sMsg)) {
                    print 
        Debug::_msg($sMsg);
                    print 
        "\n";
                }
                if (
        $bShowType) {
                    
        var_dump($mVariable);
                } else {
                    
        // second argument is supported since 4.3, let's fix it with output buffering
                    
        print_r($mVariable);
                }
                
        $sOutput ob_get_contents();
                
        ob_end_clean();
                return 
        $sOutput;
            }

            
        /**
             * @access   private
             * @warning  do not use the debug_backtrace*() functions as parameter for any method of this class
             *           othervise it might end in an infinite loop
             */
            
        function _backtrace()
            {
                
        $aBacktrace debug_backtrace();
                
        $aOutput = array(Debug::_msg('BACKTRACE'));
                for (
        $i 1$x count($aBacktrace); $i $x; ++$i) {
                    
        $aOutput[] = sprintf('[%u] %s:%u'$x $i$aBacktrace[$i]['file'], $aBacktrace[$i]['line']);
                }
                if (
        count($aOutput) == 0) {
                    return 
        '';
                }
                return 
        implode("\n"$aOutput);
            }

            
        /**
             * triggers in case of an argument error
             *
             * @static
             * @access private
             * @param integer $argumentNumber number of the argument
             * @param mixed $argument argument that triggered the error
             * @param mixed $expected type the argument should acutally be
             * @param integer $additionalBacksteps relevant backtrace step
             */
            
        function _triggerArgument($argumentNumber$is$expected$step)
            {
                
        // get backtrace route and cut off {System} entries
                
        $backtrace debug_backtrace();
                
        $backtrace $backtrace[$step];
                
        $call ltrim(@$backtrace['class'] . '::' $backtrace['function'], ':');
                
        trigger_error(sprintf(SYSTEM_ERROR_ARGUMENT$call$argumentNumber$is$expected,
                                      
        $backtrace['file'], $backtrace['line']),
                              
        SYSTEM_ERRNO_ARGUMENT);
            }

            
        /**
             * analyses a given argument
             * @static
             * @access private
             * @param mixed $argument argument to analyse
             * @return string argument type
             */
            
        function _analyseArgument($argument)
            {
                
        $analysis = array(strtolower(gettype($argument)));
                switch (
        $analysis[0]) {
                    case 
        'object':
                        
        $analysis[] = strtolower(get_class($argument));
                        break;
                    case 
        'array':
                        if (
        array_merge($argument) == array_merge(array_values($argument))) { // numeric keys
                            
        $analysis[] = $count count($argument);
                            if (
        $count && $argument == array_merge($argument)) { // keys starting with index 0, incrementing 1 per element
                                
        $analysis[] = 'i';
                            }
                        } else { 
        // string keys (assoc array)
                            
        $keys array_keys($argument);
                            
        sort($keys);
                            
        $analysis array_merge($analysis$keys);
                        }
                        break;
                }
                if (
        count($analysis) == 1) {
                    return 
        $analysis[0];
                } else {
                    return 
        $analysis[0] . '(' implode(','array_slice($analysis1)) . ')';
                }
            }
        }
        ?>

        Kommentar


        • #5
          Die neueste Variante verwendet jetzt alles, was debug_backtrace() so liefert, also auch aufrufende Methoden und ihre Parameter. Bei INT/DOUBLE und BOOL jeweils den Wert, bei Strings die ersten 15 Zeichen, bei Objektparametern deren Klasse:

          PHP-Code:
          <?php
          /**
           * @author Christian Reinecke <reinecke@bajoodoo.com>
           * @version 2.0
           * @since 2007-05-16
           * @license no
           */
          abstract class Debug
          {
              
          /**
               * @desc call with as much parameters as you like; script will exit after output
               * @param mixed [optional]
               * @return null
               */
              
          public static function stop()
              {
                  
          $glue   PHP_EOL PHP_EOL;
                  
          $output = array();
                  for (
          $i 0$k 1$x func_num_args(); $i $x; ++$i, ++$k) {
                      
          $arg func_get_arg($i);
                      
          $output[] = "DEBUG ARG $k:";
                      
          $output[] = self::_getVariable($arg);
                  }
                  
          $output[] = self::_getBacktrace($glue1);
                  
          $output[] = self::_getMemoryUsage();
                  
          $output[] = self::_getTimestamp();
                  
          $output[] = "DEBUG STOP";
                  
          $output   implode($glue$output);
                  
          self::_sendHeaders();
                  
          self::_flush($output);
                  exit;
              }

              
          /**
               * @desc call with as much parameters as you like
               * @param mixed [optional]
               * @return null
               */
              
          public static function write()
              {
                  
          $glue   PHP_EOL PHP_EOL;
                  
          $output = array();
                  for (
          $i 0$k 1$x func_num_args(); $i $x; ++$i, ++$k) {
                      
          $arg func_get_arg($i);
                      
          $output[] = "DEBUG ARG $k:";
                      
          $output[] = self::_getVariable($arg);
                  }
                  
          $output[] = self::_getBacktrace($glue1);
                  
          $output[] = self::_getMemoryUsage();
                  
          $output[] = self::_getTimestamp();
                  
          $output   implode($glue$output);
                  
          self::_flush($output);
              }

              
          /**
               * @desc call with as much parameters as you like; they will be converted to strings; script will exit after output
               * @param mixed [optional]
               * @return null
               */
              
          public static function string()
              {
                  
          $glue   PHP_EOL PHP_EOL;
                  
          $output = array();
                  for (
          $i 0$k 1$x func_num_args(); $i $x; ++$i, ++$k) {
                      
          $arg func_get_arg($i);
                      
          $output[] = "DEBUG STRING ARG $k:";
                      
          $output[] = self::_getVariable((string)$arg);
                  }
                  
          $output[] = self::_getBacktrace($glue1);
                  
          $output[] = self::_getMemoryUsage();
                  
          $output[] = self::_getTimestamp();
                  
          $output[] = "DEBUG STOP";
                  
          $output   implode($glue$output);
                  
          self::_sendHeaders();
                  
          self::_flush($output);
                  exit;
              }

              
          /**
               * @desc call with as much parameters as you like, arguments will be passed to error_log()
               * @see http://de.php.net/manual/en/function.error-log.php
               * @param mixed [optional]
               * @return bool error_log
               */
              
          public static function log()
              {
                  
          $glue   "; ";
                  
          $output = array();
                  for (
          $i 0$k 1$x func_num_args(); $i $x; ++$i, ++$k) {
                      
          $arg func_get_arg($i);
                      
          $output[] = "DEBUG ARG $k:";
                      
          $output[] = self::_getVariable($arg);
                  }
                  
          $output[] = self::_getBacktrace($glue1);
                  
          $output[] = self::_getMemoryUsage();
                  
          $output[] = self::_getTimestamp();
                  
          $output   implode($glue$output);
                  return 
          error_log($output);
              }

              public static function 
          on()
              {
                  throw new 
          Exception("deprecated");
              }

              public static function 
          off()
              {
                  throw new 
          Exception("deprecated");
              }

              public static function 
          minilog()
              {
                  throw new 
          Exception("deprecated");
              }

              public static function 
          report($sSuperGlobals 'GPCSESVEF'$bExit false)
              {
                  throw new 
          Exception("deprecated");
              }

              public static function 
          table($aArray$bPrint true$sPreTitle ''$iDepth 0)
              {
                  throw new 
          Exception("deprecated");
              }

              public static function 
          argument($arg$expected$argumentNumber 1$steps 0)
              {
                  throw new 
          Exception("deprecated");
              }

              public static function 
          arguments($argv$argvExpected)
              {
                  throw new 
          Exception("deprecated");
              }

              protected static function 
          _getTimestamp()
              {
                  list (
          $usec$sec) = explode(" "microtime());
                  
          $usec substr($usec2);
                  return 
          "DEBUG TIMESTAMP $sec.$usec";
              }

              protected static function 
          _getMemoryUsage()
              {
                  
          $memoryEmalloc number_format(memory_get_usage(false));
                  
          $memoryReal    number_format(memory_get_usage(true));
                  return 
          "DEBUG MEMORY $memoryEmalloc of $memoryReal";
              }

              protected static function 
          _getVariable($variable)
              {
                  
          ob_start();
                  
          var_dump($variable);
                  return 
          ob_get_clean();
              }

              protected static function 
          _getBacktrace($glue$slice)
              {
                  foreach (
          debug_backtrace() as $i => $trace) {
                      
          $file     = isset($trace["file"])     ? $trace["file"]     : "null";
                      
          $line     = isset($trace["line"])     ? $trace["line"]     : "null";
                      
          $class    = isset($trace["class"])    ? $trace["class"]    :  null;
                      
          $function = isset($trace["function"]) ? $trace["function"] : "null";
                      
          $type     = isset($trace["type"])     ? $trace["type"]     :  null;
                      
          $args     = isset($trace["args"])     ? implode(", "array_map(array(__CLASS__"_getBeautifiedArgument"), $trace["args"])) : null;
                      
          $output[] = sprintf("[%2s] %s:%s\n     %s%s%s(%s)",
                                  
          $i$file$line$class$type$function$args);
                  }
                  
          $output array_slice($output$slice);
                  
          array_unshift($output"DEBUG BACKTRACE");
                  return 
          implode($glue$output);
              }

              protected static function 
          _flush($string)
              {
                  echo 
          "<pre>"PHP_EOL$stringPHP_EOL"</pre>";
                  
          flush();
              }

              protected static function 
          _getBeautifiedArgument($arg)
              {
                  if (
          is_int($arg) || is_double($arg)) {
                      return 
          $arg;
                  }
                  if (
          is_string($arg)) {
                      if (
          mb_strlen($arg) > 15) {
                          return 
          '"' mb_substr($arg015) . '"[..]';
                      }
                      return 
          '"' $arg '"';
                  }
                  if (
          is_bool($arg)) {
                      return 
          $arg "true" "false";
                  }
                  if (
          is_array($arg)) {
                      return 
          "array(" count($arg) . ")";
                  }
                  if (
          is_object($arg)) {
                      return 
          get_class($arg);
                  }
                  return 
          gettype($arg);
              }

              protected static function 
          _sendHeaders()
              {
                  if (!
          headers_sent()) {
                      
          header("Content-Type: text/plain; charset=utf-8");
                      
          header("HTTP/1.1 500 Internal Server Error");
                  }
              }
          }
          ?>
          Beispiel-Ausgabe bei Debug::stop():

          Code:
          DEBUG ARG 1:
          
          string(30) "das ist ein gaaanz langer text"
          
          
          DEBUG ARG 2:
          
          bool(true)
          
          
          DEBUG ARG 3:
          
          int(-1)
          
          
          DEBUG BACKTRACE
          
          [ 1] /srv/dev/christian/ais.flashmapped.com/application/controllers/ProjectsController.php:160
               Debug::stop("das ist ein gaa"[..], true, -1)
          
          [ 2] /srv/dev/christian/ais.flashmapped.com/library/classes/Zend/Controller/Action.php:494
               ProjectsController->managestructureAction()
          
          [ 3] /srv/dev/christian/ais.flashmapped.com/library/classes/Zend/Controller/Dispatcher/Standard.php:285
               Zend_Controller_Action->dispatch("managestructure"[..])
          
          [ 4] /srv/dev/christian/ais.flashmapped.com/library/classes/Zend/Controller/Front.php:934
               Zend_Controller_Dispatcher_Standard->dispatch(Zend_Controller_Request_Http, Zend_Controller_Response_Http)
          
          [ 5] /srv/dev/christian/ais.flashmapped.com/htdocs/index.html:128
               Zend_Controller_Front->dispatch()
          
          DEBUG MEMORY 17,284,808 of 17,301,504
          
          DEBUG TIMESTAMP 1240844036.60305400
          
          DEBUG STOP
          "Mein Name ist Lohse, ich kaufe hier ein."

          Kommentar


          • #6
            LOL, war gerade irritiert, was diese Methoden machen sollen
            throw new Exception("deprecated");
            Warum hast'n on/off ausgemustert? Ist doch an sich ganz praktisch.
            --

            „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
            Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


            --

            Kommentar


            • #7
              Oh, ne sollte nur kompatibel zur Vorversion sein, das sollte hier garnicht committet werden. Global ausschalten hatte ich nie verwendet.
              "Mein Name ist Lohse, ich kaufe hier ein."

              Kommentar


              • #8
                Hihi, ja, das habe ich dann auch irgendwie erkannt.

                Ich habe seit Deiner Erstveröffentlichung damals auch die ein oder andere Debugklasse geschrieben. In der letzten habe ich auch eine on/off Methode, allerdings mit einem Ausgabemodus-Parameter. Dort kann ich statt direkt ausgeben auch "gepuffert" wählen und die Ausgabe bis zu einem explizitem Flush (oder einem implizitem Flush am Scriptende) zurückhalten. Damit kann man zum einen vor Headerausgaben ohne "headers sent"-Problematik debuggen und zum anderen Ausgaben schön innerhalb des HTML Bereichs (oder sogar bspw. im Contentbereich einer Website) ausgeben lassen.
                --

                „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                --

                Kommentar


                • #9
                  Zeig mal
                  "Mein Name ist Lohse, ich kaufe hier ein."

                  Kommentar


                  • #10
                    Ist jetzt nüscht dollet, hatte schon ausgeklügeltere Methoden. Aber war auch nur für ne kleine Redaxo-Erweiterung…

                    PHP-Code:
                    <?php

                    define 
                    ('nk_HIDE_ERRORS'               0);
                    define ('nk_SHOW_ERROR_ON_APPEARANCE'  1);
                    define ('nk_FLUSH_ERRORS_ON_EXIT'      2);
                    define ('nk_LOG_ERRORS'                4); // n.y. implemented

                    define ('nk_DEBUG_MODE_DIRECT'         1);
                    define ('nk_DEBUG_MODE_FLUSH'          2);


                    # ------------------------------------------------------------------------------
                    #    Klasse nk_Debug
                    # ------------------------------------------------------------------------------
                    /*

                      Stellt grundlegende Funktionen zur Ausgabe von Fehler- und Prüfmeldungen
                      bereit. Methoden sind durchgängig statisch implementiert.
                      Ausgaben erfolgen nur, wenn das Debugging mit nk_Debug::on eingeschaltet
                      wurde. Eine Besonderheit stellt auch noch die Pufferung dar.

                      - Puffer und Ausgabemodus -

                      Die Debugklasse kann Meldungen und Dumps puffern, um sie erst auf expliziten
                      Aufruf an einer spezifischen Stelle (bspw. Body eines HTML Dokuments) auszu-
                      geben. Für nk_Debug::on kann dazu eine Konstante übergeben werden, die dieses
                      Verhalten regelt:

                        nk_DEBUG_MODE_DIRECT                (default) Ausgabe bei dump-Aufruf
                        nk_DEBUG_MODE_FLUSH                 Pufferung bis zum expliziten Aufruf
                                                            nk_Debug::flush

                      - Fehlerverarbeitung -

                      Die Debugklasse wird verwendet, um Fehlerausgaben/-verarbeitung zu erzeugen.
                      Die Aktion ist abhängig vom gesetzten Fehlerverarbeitungsmodus:

                        nk_HIDE_ERRORS                      keine Ausgabe
                        nk_SHOW_ERROR_ON_APPEARANCE         Fehler beim Auftreten anzeigen
                        nk_FLUSH_ERRORS_ON_EXIT             Fehler puffern und bei einem schweren
                                                            Fehler oder einem explizitem flush
                                                            ausgeben
                        nk_LOG_ERRORS                       Fehler in ein Logfile schreiben (n.y.i.)


                      - Fehlerpufferung -

                      Via nk_FLUSH_ERRORS_ON_EXIT können Fehlermeldungen gesammelt und an einer
                      oder mehreren Stellen explizit ausgegeben werden (Flush). Da ein kritischer
                      Fehler die Anwendung beendet (und die Verarbeitung dann nicht mehr erfolgen
                      würde) findet beim Auftreten von kritischen Fehlern ein implizites Flush
                      statt.


                      Konstanten/Flags -------------------------------------------------------------

                        nk_DEBUG_MODE_DIRECT                Debug-Ausgabeverhalten, Beschreibung
                        nk_DEBUG_MODE_FLUSH                 siehe "Puffer und Ausgabemodus"

                        nk_HIDE_ERRORS                      Fehler-Verarbeitungsverhalten,
                        nk_SHOW_ERROR_ON_APPEARANCE         Beschreibung siehe "Fehlerverarbeitung"
                        nk_FLUSH_ERRORS_ON_EXIT
                        nk_LOG_ERRORS


                      Abhängigkeiten ---------------------------------------------------------------

                        M  nk_Error::getStack               Holt den Fehlerstack ab, um ihn zu
                                                            verarbeiten
                        K  nk_ERROR_CRITICAL                Konstante für kritischen Fehlertyp


                      Eigenschaften ----------------------------------------------------------------

                        iMode                               Debuggin-Modus
                                                            (vgl. "Puffer und Ausgabemodus")
                        iErrorMode                          Fehler-Verarbeitungssetting
                                                            (vgl. "Fehlerverarbeitung")
                        iViewErrorTrace                     Ruft Backtrace auf
                        aBuffer                             Puffer für Ausgaben im Buffer-Modus


                      Interface (Methoden) ---------------------------------------------------------

                        void = ::on ([int Mode])
                        void = ::off (void)
                        void = ::flush (void)
                        void = ::setErrorHandling (int Mode [, bool ViewTrace [, bool Log]])
                        void = ::flushErrors (void)
                        void = ::dump ([string Message [, mixed Listing [, mixed Var ..]]])

                    */
                    class nk_Debug
                      
                    {
                      static 
                    $iMode           false;
                      static 
                    $iErrorMode      nk_SHOW_ERROR_ON_APPEARANCE;
                      static 
                    $iViewErrorTrace false;
                      static 
                    $aBuffer         = array ();


                      
                    # ---------------------------------------------- Methoden: Debugging Status --


                    /*
                      public
                      void = ::on ([int Mode])

                        Schaltet das Debugging ein.


                        Parameter:    ~ Mode                Gibt zusätzlich den Ausgabemodus an
                                                            direkt oder gepuffert (siehe Klassen-
                                                            beschreibung), default ist Direktausgabe
                        Rückgabewert:   -
                      --------------------------------------------------------------------------- */
                      
                    public static function on ($iMode nk_DEBUG_MODE_DIRECT)
                        {
                        
                    self::$iMode $iMode;
                        }



                    /*
                      public
                      void = ::off (void)

                        Schaltet das Debugging aus.


                        Parameter:      -
                        Rückgabewert:   -
                      --------------------------------------------------------------------------- */
                      
                    public static function off ()
                        {
                        
                    self::$iMode false;
                        }



                    /*
                      public
                      void = ::flush (void)

                        Gibt alle bisherigen Debugging-Daten aus dem Puffer (siehe Klassen-
                        beschreibung) aus und leert anschließend den Puffer.


                        Parameter:      -
                        Rückgabewert:   -
                      --------------------------------------------------------------------------- */
                      
                    public static function flush ()
                        {
                        echo 
                    implode ("\n" self::$aBuffer);
                        
                    self::$aBuffer = array ();
                        }



                      
                    # ----------------------------------------------- Methoden: Initialisierung --



                    /*
                      public
                      void = ::setErrorHandling (int Mode [, bool ViewTrace [, bool Log]])

                        Setzt das Verhalten für die Fehlerverarbeitung,
                        siehe auch nk_Error->process ()


                        Parameter:      Mode                globaler Fehlermodus (siehe Klassen-
                                                            beschreibung/Fehlerhandlings
                                        ViewTrace           Ausgabe des Fehler-Backtrace einschalten
                                        Log                 Fehler loggen
                        Rückgabewert:   -
                      --------------------------------------------------------------------------- */
                      
                    public static function setErrorHandling ($iMode $bViewTrace true $bLog true)
                        {
                        
                    self::$iErrorMode      $iMode;
                        
                    self::$iViewErrorTrace $bViewTrace;
                        }



                      
                    # -------------------------------------------- Methoden: Fehlerverarbeitung --



                      /*
                      public
                      void = ::flushErrors (void)

                        Verarbeitet den gesamten Errorstack von nk_Error.
                        Nur im aktiven Debugging-Modus!

                        Wird auch durch ::processError () aufgerufen. Sollte auch am Ende der
                        Applikation als explicit Flush für den Fall der Fehlerhandlingeinstellung
                        nk_FLUSH_ERRORS_ON_EXIT gesetzt werden.

                        Achtung:        Methode erzeugt u.U. direkte Bildschirmausgabe

                        Abhängigkeiten: nk_Error
                        Parameter:      -
                        Rückgabewert:   kein, erzeugt je nach Debugging-Modus eine Ausgabe
                      --------------------------------------------------------------------------- */
                      
                    public static function flushErrors ()
                        {
                        
                    # -- Debugging off: keine Ausgabe
                        
                    if (false === self::$iMode) return;

                        
                    # -- Ausgabe des gesamten Stacks
                        
                    $aErrorStack nk_Error::getStack (true);
                        foreach (
                    $aErrorStack as $oCurrent)
                          {
                          if (
                    true === self::$iViewErrorTrace)
                            
                    self::dump ($oCurrent->getMessage () , $oCurrent->getBacktrace ());
                          else
                            
                    self::dump ($oCurrent->getMessage ());
                          }
                        }



                      
                    /*
                      public
                      void = ::processError (object Error)

                        Verarbeitet das als Parameter übergebene Fehlerobjekt.
                        Je nach Fehler-Handling tritt ein anderes Verhalten in Erscheinung,
                        siehe Klassenbeschreibung/Fehlerhandlings
                        Nur im aktiven Debugging-Modus!

                        Achtung:        Methode erzeugt u.U. direkte Bildschirmausgabe


                        Parameter:      Error               nk_Error Objekt
                        Rückgabewert:   kein, erzeugt je nach Debugging-Modus eine Ausgabe
                      --------------------------------------------------------------------------- */
                      
                    public static function processError ($oCurrent)
                        {
                        
                    # -- Debugging off: keine Ausgabe
                        
                    if (false === self::$iMode) return;

                        switch (
                    self::$iErrorMode)
                          {
                          
                    # -- Fehlermodus: Sofortige Ausgabe für jeden Fehler
                          
                    case nk_SHOW_ERROR_ON_APPEARANCE:

                            if (
                    true === self::$iViewErrorTrace)
                              
                    // später Debugging List
                              
                    self::dump ($oCurrent->getMessage () , $oCurrent->getBacktrace ());
                            else
                              
                    self::dump ($oCurrent->getMessage ());
                            break;


                          
                    # -- Fehlermodus: Komplette Fehlerausgabe bei einem kritischen Fehler
                          
                    case nk_FLUSH_ERRORS_ON_EXIT:

                            
                    # -- kritischer Fehler, nach dem kommt nix mehr
                            
                    if (nk_ERROR_CRITICAL === $oCurrent->getType ())
                              {
                              
                    self::flushErrors ();
                              }
                            break;

                          
                    # -- Fehlermodus: Keine Ausgabe oder nur Log
                          
                    case nk_HIDE_ERRORS:
                          default:

                            
                    # -- keine Ausgabe
                            
                    break;
                          }
                        }



                      
                    # --------------------------------------------- Methoden: Bildschirmausgabe --



                    /*
                      public
                      void = ::dump ([string Message [, mixed Var ..]])

                        Gibt eine Meldung und/oder ein Variablenlisting als Debugging-Box aus oder
                        schreibt diese Daten in den Puffer (siehe Klassenbeschreibung).

                        Achtung:        Methode erzeugt u.U. direkte Bildschirmausgabe
                                        Ausgabe ist abhängig von Debug-Status und von der
                                        Ausgabepufferung der Debuggingklasse.


                        Parameter:    ~ Message             Meldung (z.B. Fehlernachricht)
                                      ~ Var                 Variablenangabe, Backtrace o.ä.
                                                            bei Bedarf beliebig viele Variablen
                        Rückgabewert:   kein, erzeugt je nach Debugging-Modus eine Ausgabe
                      --------------------------------------------------------------------------- */
                      
                    public static function dump ($sMessage null $mListing null )
                        {
                        
                    # -- Debugging off: keine Ausgabe
                        
                    if (false === self::$iMode) return;

                        
                    $sOut  '<pre class="error" ' .
                                 
                    'style="border:2px solid #800;padding:5px;background-color:#eee;margin-bottom:2px;">';
                        
                    $sOut .= "\n";

                        
                    # -- optional Meldung ausgeben
                        
                    if (null !== $sMessage)
                          {
                          
                    $sOut .= $sMessage "\n";
                          }

                        if (
                    null !== $mListing)
                          {
                          
                    # -- optionale Argumente auslesen und Message entfernen
                          
                    $aArgs func_get_args ();
                          
                    array_shift ($aArgs);

                          
                    # -- alle optionalen Argumente dumpen
                          
                    foreach ($aArgs as $mArgument)
                            {
                            
                    $sOut .= print_r ($mArgument 1);
                            
                    $sOut .= "\n";
                            }
                          }
                        
                    $sOut .= '</pre>';

                        
                    # -- Ausgabe je nach Pufferverhalten
                        
                    switch (self::$iMode)
                          {
                          case 
                    nk_DEBUG_MODE_FLUSH:
                            
                    self::$aBuffer[] = $sOut;
                            break;

                          default:
                          case 
                    nk_DEBUG_MODE_DIRECT:
                            echo 
                    $sOut;
                            break;
                          }
                        
                        if (
                    function_exists ('fb'))
                          {
                          
                    fb ($sOut);
                          }
                        }
                      }
                    PS: Für den Fall, dass definitiv bereits CSS geladen wurde sind die Stylesheets aus dump () in nem separaten CSS File natürlich besser aufgehoben. Daher die class="error" Angabe.
                    --

                    „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                    Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                    --

                    Kommentar


                    • #11
                      Hm verstehe ich nicht so ganz, wenn ich dump() einen Array übergebe, bekomme ich als Ausgabe ja nur "Array"?!
                      "Mein Name ist Lohse, ich kaufe hier ein."

                      Kommentar


                      • #12
                        Naja, nee. Der erste Parameter ist (optional) eine zusätzliche Nachricht als Überschrift. Wußte keinen anderen Weg, um immer noch variable Parameteranzahl zu unterstützen. Früher hatte ich mal zwei Dump-Methoden, eine mit Bemerkung und eine ohne. War auch nicht praktischer...

                        [edit]
                        Habs bisher auch nur mal für die Ausgabe eines Wertes oder einer Meldung an einer bestimmtem Stelle gebraucht. Daher fällt mir auch gerade erst auf, dass ich nicht mal ne Zeilennummer mit ausgebe. In Redaxo mit sein eval-Modulen ist mit Zeilennummern allerdings eh nicht viel.

                        Werd bei Gelegenheit mal noch mal dran basteln.

                        PS:
                        Das hier gibt im obigen Code die bessere Ausgabe als print_r (print_r-Style + Typen + Darstellung von BOOL):
                        PHP-Code:
                                ob_start ();
                                
                        var_dump ($mArgument);
                                
                        $sOut    .= preg_replace ('/=\>[' PHP_EOL ']+[\t\040]*([^' PHP_EOL ']*)/' ' => $1' ob_get_contents ());
                                
                        ob_end_clean (); 
                        --

                        „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                        Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                        --

                        Kommentar


                        • #13
                          Ich find deine Klasse zu kompliziert Debug-Ausgaben sind für mich wirklich nur schnelle Dumpausgaben um zu schauen was ich hab und wo ich bin, als Feature noch fürs ErrorLog, wobei ich das eigentlich auch schon nie brauche ..
                          "Mein Name ist Lohse, ich kaufe hier ein."

                          Kommentar


                          • #14
                            ich nutze den ZendDebugger (auf dme Server) in Kombination mit dem Zend Studio for Eclipse, Browserausgaben sind immer so ne Sache .....

                            alternativ würde sich pdt / PHP Ecplipse in Kombination mit Xdebug anbieten ?

                            Kommentar


                            • #15
                              XDebug schraubt selbst ziemlich an der Performance
                              "Mein Name ist Lohse, ich kaufe hier ein."

                              Kommentar

                              Lädt...
                              X