Bonjour, bonjour,
est-ce que quelqu'un dans l'assemblée aurait connaissance d'un script/outil, je ne sais quoi, qui permettrait de dresser un arbre des dépendances d'un script/programme php ?
Autrement dit, en donnant un nom de fichier (index.php), cet outil retrouve, récursivement, tous les include/require, et les renvoie avec leur chemin complet (prenant en compte l'utilisation de variables et constantes dans l'include).
Ou mieux/aussi, qui dessine le graphe correspondant, et/ou permet de naviguer dans le source.
Voila. Ce sera tout pour aujourd'hui. :-)
Grep, preg_match_all() font bien l'affaire pour dépanner, mais avant de me lancer dans un truc plus complexe, si ça existe déjà, je suis preneur (et je ne pense pas être le seul).
Merciiiiiiii !
# Oui et Non
Posté par Cali_Mero . Évalué à 3.
Par contre, j'ai du mal à imaginer ce que tu veux dire par :
Grep, preg_match_all() font bien l'affaire pour dépanner,
En effet, tu sais que les include()/include_once()/require()/require_once() peuvent être influencés dynamiquement (c'est là d'ailleurs que réside une partie de la puissance de php), par exemple :
$truc='unevaleur';
// du code
$fichier = $truc.'.php';
$a = '/var/toto/plop/';
ini_set('include_path',$a);
include($fichier);
Dans ce genre de cas (très fréquent) tu t'attends à ce que le programme te sorte une dépendance vers le fichier /var/toto/plop/unevaleur.php ? Si oui, tu rêves...
En gros, si tu connais les sources de ton appli, tu devrais pouvoir te débrouiller et faire un rapidement un outil qui fait exactement ce que tu veux, avec les expressions régulières par exemple.
Mais tu ne trouveras pas de script qui marche à 100% quelle que soit l'appli, à cause du genre de code dont je t'ai mis un exemple ci-dessus, totalement impossible à analyser à moins d'éxécuter le code....
Mon conseil perso : vu que tu es capable de te débrouiller avec les expressions régulières, termine le boulot que tu as commencé "pour dépanner".
[^] # Re: Oui et Non
Posté par romain . Évalué à 4.
PHPDoc fait effectivement pas mal le boulot ; enfin... si le code à analyser a été correctement commenté, sinon ça n'a pas grand intérêt. :-)
Dans ce genre de cas (très fréquent) tu t'attends à ce que le programme te sorte une dépendance vers le fichier /var/toto/plop/unevaleur.php ? Si oui, tu rêves...
Avec seulement un grep ou un regexp, c'est sûr, ce serait difficile dans ce cas.
Sinon, c'est parfaitement possible, à condition de parser le code ; "reste à" bien coder ça pour que ça reste propre.
Quand à dire que ce genre de code se retrouve souvent, c'est vrai ; malheureusement. C'est crade, spaghettis, et potentiellement dangereux (si c'est mal encadré). Mais comme c'est un avis purement personnel (bien qu'appuyé par l'expérience), on ne va pas en faire un gâteau, hein ? ;-)
En gros, si tu connais les sources de ton appli,
C'est là que le bât blesse ; ce genre d'outil ne m'intéresse surtout que dans la mesure où on me catapulte une énorme appli sans documentation, et que j'ai besoin de l'assimiler relativement vite. Pouvoir naviguer dans les sources aide grandement.
[^] # Re: Oui et Non
Posté par Cali_Mero . Évalué à 2.
Tu dois être devant une application alien avec 2000 fichiers qui s'incluent dans tous les sens... Toutes mes condoléances !
Je n'étais pas sûr que tu décrives ce cas, je pensais plutot que tu souhaitait pouvoir afficher un "rapport" des dépendances des fichiers d'une grosse appli à toi (histoire de sortir un beau diagramme hiérarchique dont certains profs de dev raffolent). Le problème était, dans ce cas, plus simple car tu connais les écueils de ton code... Ce qui n'est pas ton cas.
Sinon, c'est parfaitement possible, à condition de parser le code ; "reste à" bien coder ça pour que ça reste propre.
Je dirais, moi, que ce n'est pas possible : observe mon exemple (toutes considérations de sécurité complètement mises à part, je me mets dans ta situation en découvrant une application que je ne connais pas encore) :
les fonctions include() et ini_set() peuvent prendre leurs paramètres depuis des variables. En imaginant que seules ces fonctions peuvent permettre d'agir sur les dépendances entre les différents fichiers qui composent ton programme (ce qui n'est bien sûr pas le cas), l'analyseur de dépendances devrait parser le code à l'envers, en respectant les dépendances, pour traquer toutes les valeurs possibles de ces variables ? ca me parait dingue, voire carrément impossible dans le cas du trou de sécu typique : la variable est directement en provenance de l'utilisateur ($_GET, $_POST, $_COOKIE...).
Quand à dire que ce genre de code se retrouve souvent, c'est vrai ; malheureusement. C'est crade, spaghettis, et potentiellement dangereux (si c'est mal encadré). Mais comme c'est un avis purement personnel (bien qu'appuyé par l'expérience), on ne va pas en faire un gâteau, hein ? ;-)
Un de mes avis personnels, motivé par l'expérience : les programmes les plus efficaces en php sont ceux qui exploitent la souplesse des différentes fonctions "coup de bistouri" qui facilitent la vie (explode, implode, include, header...).
Enfin, si ton appli ne rentre pas dans cette catégorie... On peut espérer qu'un analyseur de dépendances devrait faire très bien son boulot. Mais bonjour l'arrachage de cheveux si tu dois compter dessus et que ce n'est pas le cas !
Pour info, je suis en train de bosser sur une appli qui intégrerait ce genre de fonctionnalités, voilà pourquoi j'ai bien réfléchi à la question.
# Grosse bidouille
Posté par pifou . Évalué à 4.
J'ai fait un script Perl très sale pour réaliser ce genre de chose à l'époque ou je développais du PHP en stage (y'a 2, 3 ans maintenant). En gros j'avais une applii assez grosse dans laquelle j'avais des problèmes de doubles inclusion de fichier à différent niveau.
En gros, le code Perl est vraiment une honte : utilisation d'un algo maison pour le parsing des arguments (au lieu d'utiliser GetOpt), code GTK mélangé au code de recherche ... Et j'ai un peu la flemme de le refaire propre :) (d'autant plus que je ne fais plus de PHP).
Voici comment il marche, tu lui passes en paramètre le répertoire racine de ton projet, il va parser tous les fichiers '.php', regarder les 'include|require|require_only|....' (si tu veux en rajouter va voir ligne 360). S'il y a une variable dans le include du genre 'include("$toto/titi.php")' il va te demander de rentrer la valeur de $toto et la stockera jusqu'à la fin de la génération des arbres (attention à ne pas avoir deux fois le même nom de variable avec des valeurs différentes). Au final, il aura construit les arbres d'inclusions et de dépendances, ces arbres peuvent être générés au format ASCII ou LaTeX (pratique pour les rapports) ou bien être affichés dans une fenêtre GTK. Je te conseille ce dernier mode bien plus pratique. Enfin l'application te demande si tu veux enregistrer la configuration des variables dans un fichier afin d'éviter de retaper toutes les variables de type $toto la prochaine fois (option -c ).
Tu trouveras l'archive de ReqInc sur http://msalvat.free.fr/reqinc.tar.gz(...) . Il n'y a que deux fichiers. Pour lancer le script reqinc.pl je te conseille de te placer dans le répertoire de ton site. Voici la ligne de commande qui a servi à générer ce screenshot http://msalvat.free.fr/reqinc.png(...) :
perl -I /où/est/decompréssé/l/archive/ /où/est/decompréssé/l/archive/reqinc.pl ./ -c /tmp/mon-site.cfg -t gtk
Bien sûr le fichier /tmp/mon-site.cfg a été généré avant par l'application en mode interactif. Dans l'interface GTK il faut bien faire attention : dans le screenshot on a l'arbre d'inclusion (voir titre de la fenêtre) il faut appuyer sur le bouton "Arbre de dépendance" pour switcher sur l'arbre de dépendance, et vice versa.
En espérant que ça te serve ... bien sûr je met se fichier sous GPL si qqun à envie de le modifier (bonne chance pour comprendre le code) :).
[^] # Re: Grosse bidouille
Posté par pifou . Évalué à 2.
[^] # Re: Grosse bidouille
Posté par Gart Algar . Évalué à 2.
[^] # Re: Grosse bidouille
Posté par Cali_Mero . Évalué à 3.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.