Scriptorama.nl

Header image showing a keyboard, mouse, laptop and books on design patterns

Debugging: stacktraces

Een van de dingen die PHP lang niet (standaard) gehad heeft is een stacktrace mogelijkheid. Een stacktrace is een overzicht van hoe je op een bepaald punt in je script beland bent. Een klein voorbeeldje:

stacktrace

Deze stacktraces kun je sinds PHP 4.3.0 zelf ook maken, met de hulp van debug_backtrace() en das best handig als je knie diep in de classes staat en geen idee hebt waar er nu precies iets fout gaat.

De functie debug_backtrace() geeft een array met arrays terug. Voor elke functie of klasse methode die is aangeroepen vanaf het globale bereik (global scope) krijg je een associatieve array met daarin de volgende elementen (sleutels):

  • function: naam van de aangeroepen functies
  • line: het regelnummer waar de functie werd aangeroepen
  • file: het bestand waar deze functie vanuit werd aangeroepen
  • class: de naam van de klasse (mogelijk van een object) waarvan een methode werd aangeroepen
  • type: geeft aan op welke manier de methode van een klasse werd aangeroepen. '->' als de aanroep op een object was, '::' als het een statische aanroep was
  • args: De argumenten die aan de functie werden gegeven

De naam zegt het al, het is een stacktrace en dat houdt in dat de array die debug_backtrace() retourneert zich gedraagd als een stack. Voor degene die onder een steen leven: een stack is een data structuur waar je de meest recent toegevoegde waarde bovenaan de lijst terugvindt. De bovenste array bevat dus informatie over de laatst aangeroepen functie.

PHP:
  1. /**
  2. * Kleine klasse om een stack trace mee te tonen.
  3. *
  4. * Voorbeeld aanroep:
  5. *
  6. * function test() {
  7. *  DevTools::Stacktrace();
  8. * }
  9. *
  10. * Mathieu Kooiman <info (op) scriptorama punt nl>
  11. * http://www.scriptorama.nl/
  12. */
  13.  
  14. class DevTools
  15. {
  16.   /**
  17.    * Toon een stacktrace
  18.    *
  19.    * @param returnString boolean Flag om aan te geven of het resultaat terug gegeven moet worden ipv. weergegeven
  20.    * @return string of niks
  21.    */
  22.   function Stacktrace($returnString = false)
  23.   {
  24.     $trace = debug_backtrace();
  25.    
  26.     /* De aanroep naar DevTools::Stacktrace() zit er
  27.      * standaard ook bij. Dat geloven we wel, dus
  28.      * die halen we er maar vanaf. */
  29.  
  30.     array_shift($trace);
  31.    
  32.     $result = "<style type=\"text/css\">\n.trace td { font-family: arial; font-size: 11px;}\n " ;
  33.     $result .= ".trace h3 { font-size: .9em; color: red; border-bottom: 1px dashed #c0c0c0; }</style>";
  34.     $result .= '<table class="trace" border="0" cellpadding="3">';
  35.     $result .= '<tr><td colspan="3"><h3>Stacktrace</h3></td>';
  36.  
  37.     foreach ($trace as $level => $data)
  38.     {
  39.       $result .= '</tr><tr><td>#'. $level . '</td>';
  40.       $result .= '<td>';
  41.      
  42.       if (isset($data['class'])) {
  43.         $result .= $data['class'] . $data['type'];
  44.       }
  45.  
  46.       $result .= $data['function'] . "()</td>";
  47.       $result .= sprintf("<td>[%s:%d]</td>\n", $data['file'], $data['line']);
  48.       $result .= "</tr>";
  49.  
  50.       if (isset($data['args']) && count($data['args'])> 0) {
  51.         $result .= '<tr>';
  52.         $result .= '<td>&nbsp;</td>';
  53.         $result .= '<td valign="top">Arguments:<br /></td>';
  54.         $result .= '<td>';
  55.  
  56.         foreach ($data['args'] as $key => $argument) {
  57.           $result .= "#$key: " . htmlspecialchars(print_r($argument, true)) . '<br />';
  58.         }
  59.  
  60.         $result .= '</td></tr>';
  61.       }
  62.  
  63.     }
  64.     $result .= "</table>";
  65.  
  66.     if ($returnString) {
  67.       return $result;
  68.     }
  69.  
  70.     echo $result;
  71.   }
  72.  
  73. }

Reageer ook!

Je doet $result .=, terwijl $result nog niet bestaat. Voor een site als dit vind ik dit toch een grote fout;)

Ach, grote fout, het lijkt me meer iets dat even bij het editten is misgelopen.

Bedankt voor de heads up! Het is verholpen.

Leave a comment
Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>