A la différence de nombreux autres langages (e.g. JAVA, C, C++, OCaml…), PHP n'est pas compilé et est donc très avare de messages d'erreurs. L'objet de ce qui suit est de vous donner quelques pistes pour vous aider à debugger votre futur projet de Modex.
L'idée principale sera d'inclure dans votre code PHP des commandes permettant un debuggage de vos script PHP et des diverses interactions avec MySQL. Afin de ne pas afficher systématiquement les messages liés aux debuggage, on définira une variable Booléenne permettant d'activer ou non le mode debuggage.
Bien entendu, intégrer des fonctions de debuggage à votre code, ne vous dispensera pas de le structurer, de le commenter et de l'indenter correctement. Organiser le code permettra d'éviter beaucoup d'erreurs: mieux vaut prévenir que guérir!
Votre fichier PHP à débugger contiendra les lignes suivantes, qui définissent une variable Booléenne définissant le mode (true pour debugger, false pour ignorer les commandes de debuggages) et fera appel au fichier debug.php qui va contenir les diverses fonctions de debuggages.
<? $Debug = true; require("./debug.php"); ?>
Nous allons maintenant décrire le fichier debug.php qui va contenir diverses fonctions de debuggage. A vous d'en ajouter d'autres selon vos besoins.
Commencez par prévoir dans votre fichier CSS une classe pour l'affichage des messages de debuggage. On pourra par exemple utiliser le style suivant (utilisé dans ce document pour afficher du code:
div.debug { background:lightgreen; border-style:dotted; border-color:blue; border-width:1px 1px 1px 1px; } div.debug em { font-weight: bold; font-style: normal; }
Un point important concerne l'accès à la valeur de $Debug dans les diverses fonctions de debug.php. Prenons l'exemple de la fonction suivante qui affiche un message si le mode debuggage est activé:
function debugPrintStatut(){ global $Debug; if ($Debug){ echo "<div class = 'debug'>Mode débuggage activé</div>"; } }
Vous remarquerez ici la commande global $Debug qui a pour effet que la variable $Debug, locale à la fonction debugPrintStatut fasse référence à la variable — globale — $Debug définie dans le fichier à débugger. Une alternative aurait été de passer $Debug comme paramètre de la fonction debugPrintStatut. Dans la suite nous donnons quelques fonctions de débuggage.
On peut souhaiter afficher la valeur d'une variable pour voir si celle-ci est est bien définie et possède la valeur attendue. On pourra utiliser la fonction qui suit. Cette dernière prend comme argument une chaîne de caractère qui donne le nom de la variable à afficher. Ainsi si l'on veut afficher le contenu de la variable $nomvariable on appellera la fonction debugPrintVariable("nomvariable"). Ce processus est inévitable si l'on souhaite tester l'existence ou le type de la variable à afficher. Afin de parler de la variable $nomvariable, on utilise le concept de variable dynamique: dans le code $$nomvariable fait donc référence à la variable dont le nom est $nomvariable. L'idée ici est d'avoir des noms de variables qui sont variables, c'est−à−dire un nom de variable qui est affectée et utilisée dynamiquement. Le reste du code donne un affichage selon les divers types de variables possibles.
function debugPrintVariable($nomvariable){ global $Debug; global $$nomvariable; if ($Debug){ if (isset($$nomvariable)){ if(is_array($$nomvariable)){ echo "<div class = 'debug'><em>Valeur du tableau $".$nomvariable.": </em>"; if ($$nomvariable) { echo "<ul>"; foreach ($$nomvariable as $cle => $valeur) { echo "<li>$".$nomvariable."[$cle] = $valeur</li>"; } echo "</ul>"; } echo "</div>"; } else if(is_bool($$nomvariable)){ echo "<div class = 'debug'><em>Valeur du Booléen $".$nomvariable.": </em>"; if ($$nomvariable){ echo "true"; } else{ echo "false"; } echo "</div>"; } else if(is_string($$nomvariable)){ echo "<div class = 'debug'><em>Valeur de la chaîne de caractères $".$nomvariable.": </em>".$$nomvariable."</div>"; } else if(is_numeric($$nomvariable)){ echo "<div class = 'debug'><em>Valeur de la variable numrique $".$nomvariable.": </em>".$$nomvariable."</div>"; } else{ echo "<div class = 'debug'><em>La variable $".$nomvariable." existe mais je ne suis pas sûr de l'afficher correctement. Sa valeur est </em>".$$nomvariable."</div>"; } } else{ echo "<div class = 'debug'><em>La variable $".$nomvariable." n'est pas définie!</em></div>"; } } }
function debugPrintVariablePOST(){ global $Debug; if ($Debug){ debugPrintVariable("_POST"); } } function debugPrintVariableGET(){ global $Debug; if ($Debug){ debugPrintVariable("_GET"); } } function debugPrintVariableSESSION(){ global $Debug; if ($Debug){ debugPrintVariable("_SESSION"); } }
mysql_connect("localhost", "root", "") or die("Erreur de connexion à MySQL"); mysql_select_db("Modex") or die("Erreur de connexion à la base de données"); $query = "SELECT * FROM News"; debugPrintVariable("query"); $reponse = mysql_query($query); if (!$reponse) echo "Erreur SQL ".mysql_error()." sur ".$query;
On pourrait évidemment factoriser tout ceci en une fonction qui prend en argument un chaîne de caractère codant une requête MySQL et l'exécute tout en donnant des informations supplémentaires si on est en mode débuggage.
function debugRequeteSQL($Requete){ global $Debug; if ($Debug){ $reponse = mysql_query($Requete); if ($reponse){ echo "<div class = 'debug'><em>La requête $Requete a été effectuée avec succcès </em></div>"; return $reponse; } else{ echo "<div class = 'debug'><em>La requête $Requete a provoqué l'erreur suivante: </em>".mysql_error()."</div>"; } } }
En conclusion, n'oubliez pas d'organiser au mieux votre code, et n'hésitez pas à adapter les fonctions précédentes à vos besoin.