Bonjour !
J'ai un "site" en php d'une soixantaine de pages, avec plein de variables et d'inclusions de fichiers.
J'aimerais me faire un graph qui me permette de savoir quel page appelle quelle page, quels variables sont définis où, etc.
Savez vous s'il existe déjà une petite appli permettant ça (je ne tiens pas forcément à ce que l'appli établissent les liens elle-mêmes. Je peux très bien rentrer toutes les informations à la main. C'est juste que sur PC, c'est plus facile pour modifier le graph lors de l'évolution de certaines pages...) ?
Forum Programmation.php graphe des liaisons entre fichiers
19
août
2004
# Dox
Posté par Pooly (site web personnel) . Évalué à 2.
s'il s'agit de savoir quel URL appel quelle URL, aucune idée.
Sinon tu peux utiliser doxygen pour savoir quel fichier inclus quel fichier.
Cerise sur le gateau, Dox te permet avec Dot de coder toi meme tes propres graphs, donc si tu veux coder a la main quelle URL mene a quelle URL c'est possible.
# Une solution
Posté par bobert . Évalué à 1.
La subtilité, pour éviter de pourrir le graphe, c'est de regrouper en un même noeud les fichiers qui ont les mêmes inclusions.
Sinon une limitation fondamentale du programme c'est qu'il attend des fichiers aux noms distincts ; lever cette limitation demanderait pas mal d'efforts supplémentaires... moi je m'arrête là.
[^] # php2dot
Posté par bobert . Évalué à 2.
#!/usr/bin/python # -*- coding: iso-8859-1 -*- # # Copyright (C) 2004 Nicolas Girard < bobert at dlfp dot org > # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. import os,sys,re from os.path import join from itertools import ifilter from sets import Set class Finder: """Parcourt une hiérarchie de répertoires à partir de startDirectory""" def __init__(self,startDirectory): self.walker = os.walk(startDirectory) def walk(self): while 1: root, dirs, files = self.walker.next() for file in files: yield (root,file) def phpFiles(self): isPhp = lambda (r,f):f.endswith('.php') or f.endswith('.php3') return ifilter(isPhp,self.walk()) def find(dir): return Finder(dir) class PhpFile: include = re.compile(".*include\s*\(['\"](\S+)['\"]\)\s*;") def __init__(self,dir,name): (self.dir,self.name)=(dir,name) def includes(self): f=open(join(self.dir,self.name),'r') lines=f.readlines() f.close() for line in lines: if PhpFile.include.match(line): yield PhpFile.include.match(line).group(1).split('/')[-1] class Node: def __init__(self,name,labels=[],children=Set()): (self.name,self.labels,self.children,self.nodes)=(name,labels,children,None) def mergeWith(self,node): self.labels+=node.labels def label(self): return "\\n".join(self.labels) def edges(self): return "\n".join(map(lambda child,s=self:"%s -> %s"%(s.name,child.name),self.children)) def __eq__(self,other): return self.name==other.name def __str__(self): return "%s [label=\"%s\"]\n%s"%(self.name,self.label(),self.edges()) def rank(self): """calcule le nombre de parents du noeud""" return sum(map(lambda o,s=self,:s in o.children,self.nodes)) def isExcluded(self): return self.rank()==0 and len(self.children)==0 class Graph: def __init__(self,ranksep=2,nodesep=0.5,minlen=1.5,concentrate=True,nodes=[]): self.nodes=nodes self.head=""" digraph Schema { node[shape=box]; concentrate=%s; ranksep=%f; nodesep=%f; edge[minlen=%f];\n"""%(concentrate,ranksep,nodesep,minlen) self.foot="}\n" def append(self,node): node.nodes=self.nodes self.nodes.append(node) def __getitem__(self,nodeName): res=filter(lambda node,n=nodeName:node.name==n,self.nodes) if len(res)==1: return res[0] else: return None def checkChildren(self): """On supprime les fichiers inclus ne correspondant pas à un fichier trouvé et les doublons""" for node in self.nodes: node.children = filter(lambda ch,fath=node:ch and fath!=ch, map(lambda c,s=self:self[c],node.children)) def removeExcluded(self): """supprime les noeuds exclus du graphe""" for excluded in filter(Node.isExcluded,self.nodes): self.nodes.remove(excluded) def clusterize(self): """Regroupe les fichers non-inclus par d'autres, et incluant les mêmes fichiers""" nodes = filter(lambda n:n.rank()==0,self.nodes) for node in nodes: (node.clustered,node.removed)=(False,False) for node in nodes: ch = node.children[:] for other in nodes: if other == node or other.clustered or other.removed: continue if ch==other.children: node.mergeWith(other) node.clustered=True other.removed=True for node in filter(lambda n:n.removed,nodes): self.nodes.remove(node) def __str__(self): for i in range(len(self.nodes)): self.nodes[i].name="node%d"%i return self.head+"\n".join(map(str,self.nodes))+self.foot usage=""" php2dot - Génère un script dot des relations d'inclusion entre fichiers PHP Syntaxe: php2dot startDir startDir : répertoire de recherche des fichiers PHP. La recherche est récursive. Synopsis: php2dot startDir > graph.dot dot -Tpng -ograph.png graph.dot Limitation: Les noms des fichiers PHP trouvés doivent être distincts """ if __name__=="__main__": if len(sys.argv)==1: print usage sys.exit(0) startDir=sys.argv[1] graph = Graph() for (dir,name) in find(startDir).phpFiles(): phpFile = PhpFile(dir,name) if not graph[name]: graph.append(Node(name,[name],phpFile.includes())) graph.checkChildren() graph.removeExcluded() graph.clusterize() print graph# Commentaire supprimé
Posté par Anonyme . Évalué à 1.
Ce commentaire a été supprimé par l’équipe de modération.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.