Par Nicolas SUPRIN, jeudi 11 janvier 2007 à 09:35 | PHP | #77 | rss
Voici une méthode de debbugage trés sympa, avec une petite amélioration en prime.
Travaillant depuis quelques années avec cet indispensable outil de débbugage, il m'arrivait fréquement d'oublier un print_rn dans les entrailles d'un fichier perdu au fin fond d'un projet, et le fait de devoir le retrouver, représentait bien souvent un vrai chemin de croix !
J'ai en effet rajouté un moyen de "tracer" l'appel de cette fonction print_rn.
En clair cela permet de savoir en coup d'oeil d'où est appelé un print_rn, en affichant le nom du fichier et la ligne où est effectué cet appel.
Le code de la fonction
<?php function print_rn($data, $B_echo = true) { ob_start(); var_dump($data); $c = ob_get_contents(); ob_end_clean(); $c = preg_replace("/\r\n|\r/", "\n", $c); $c = str_replace("]=>\n", '] = ', $c); $c = preg_replace('/= {2,}/', '= ', $c); $c = preg_replace("/\[\"(.*?)\"\] = /i", "[$1] = ", $c); $c = preg_replace('/ /', " ", $c); $c = preg_replace("/\"\"(.*?)\"/i", "\"$1\"", $c); $c = htmlspecialchars($c, ENT_NOQUOTES); // Expand numbers (ie. int(2) 10 => int(1) 2 10, float(6) 128.64 => float(1) 6 128.64 etc.) $c = preg_replace("/(int|float)\(([0-9\.]+)\)/ie", "'$1('.strlen('$2').') <span class=\"number\">$2</span>'", $c); // Syntax Highlighting of Strings. This seems cryptic, but it will also allow non-terminated strings to get parsed. $c = preg_replace("/(\[[\w ]+\] = string\([0-9]+\) )\"(.*?)/sim", "$1<span class=\"string\">\"", $c); $c = preg_replace("/(\"\n{1,})( {0,}\})/sim", "$1</span>$2", $c); $c = preg_replace("/(\"\n{1,})( {0,}\[)/sim", "$1</span>$2", $c); $c = preg_replace("/(string\([0-9]+\) )\"(.*?)\"\n/sim", "$1<span class=\"string\">\"$2\"</span>\n", $c); $regex = array( // Numberrs 'numbers' => array('/(^|] = )(array|float|int|string|resource|object\(.*\)|\&object\(.*\))\(([0-9\.]+)\)/i', '$1$2(<span class="number">$3</span>)'), // Keywords 'null' => array('/(^|] = )(null)/i', '$1<span class="keyword">$2</span>'), 'bool' => array('/(bool)\((true|false)\)/i', '$1(<span class="keyword">$2</span>)'), // Types 'types' => array('/(of type )\((.*)\)/i', '$1(<span class="type">$2</span>)'), // Objects 'object' => array('/(object|\&object)\(([\w]+)\)/i', '$1(<span class="object">$2</span>)'), // Function 'function' => array('/(^|] = )(array|string|int|float|bool|resource|object|\&object)\(/i', '$1<span class="function">$2</span>('), ); foreach ($regex as $x) { $c = preg_replace($x[0], $x[1], $c); } $style = ' /* outside div - it will float and match the screen */ .dumpr { margin: 2px; padding: 2px; background-color: #fbfbfb; float: left; clear: both; } /* font size and family */ .dumpr pre { color: #000000; font-size: 9pt; font-family: "Courier New",Courier,Monaco,monospace; margin: 0px; padding-top: 5px; padding-bottom: 7px; padding-left: 9px; padding-right: 9px; } /* inside div */ .dumpr div { background-color: #fcfcfc; border: 1px solid #d9d9d9; float: left; clear: both; } /* syntax highlighting */ .dumpr span.string {color: #c40000;} .dumpr span.number {color: #ff0000;} .dumpr span.keyword {color: #007200;} .dumpr span.function {color: #0000c4;} .dumpr span.object {color: #ac00ac;} .dumpr span.type {color: #0072c4;} .legenddumpr { background-color: #fcfcfc; border: 1px solid #d9d9d9; padding: 2px; } '; $style = preg_replace("/ {2,}/", "", $style); $style = preg_replace("/\t|\r\n|\r|\n/", "", $style); $style = preg_replace("/\/\*.*?\*\//i", '', $style); $style = str_replace('}', '} ', $style); $style = str_replace(' {', '{', $style); $style = trim($style); $c = trim($c); $c = preg_replace("/\n<\/span>/", "</span>\n", $c); $S_from = ''; // --- Affichage de la provenance du print_rn $A_backTrace = debug_backtrace(); if (is_array($A_backTrace) && array_key_exists(0, $A_backTrace)) { $S_from = <<< BACKTRACE {$A_backTrace[0]{'file'}} Ã la ligne {$A_backTrace[0]{'line'}} BACKTRACE; } else { $S_from = basename($_SERVER['SCRIPT_FILENAME']); } $S_out = ''; $S_out .= "<style type=\"text/css\">".$style."</style>\n"; $S_out .= '<fieldset class="dumpr">'; $S_out .= '<legend class="legenddumpr">'.$S_from.'</legend>'; $S_out .= '<pre>'.$c.'</pre>'; $S_out .= '</fieldset>'; $S_out .= "<div style=\"clear:both;\"> </div>"; if ($B_echo) { echo $S_out; } else { return $S_out; } }
Appel de la function
<?php require_once 'print_rn.php'; $A_datas = array('idParent' => -1, 'icone' => array('url', 'target', array('width'=>12, 'height'=>15)), 'intitule' => array('label'=>'Root', 'lien'=> array('url', 'target', array('width'=>12, 'height'=>15))), 'type' => 'ROOT', 'cle' => 12 ); print_rn($A_datas);
Résultat
Regardez bien la légende du fieldset, et votre vie va changer dés à présent !
Voir le script en action





T'es un génie Nico !!
LE truc qui manquait à cette fonction, j'avais essayer en vain de le faire avec les constantes magiques __FILE__ et __LINE__ mais apparemment je m'y prenais mal !
Un seul mot à dire : BRAVO ;-)
ps: je m'en vais mettre à jour tous mes sites !!
Pareil pour moi nico !!! -- t'es génial
Je te la pompe pour l'INRA !!!!
Au fait bonjour à toute la dev Team
Tiens, je serais juste tenté de répondre :
Ben vas-y, fais-toi plaisir, pompe la moi pour l'INRA !
Aucun trackback.
Pour faire un trackback sur ce billet : http://www.blog.cactuscrew.com/tb.php?id=77&chk=jlzk6e