Mit einer statischen Code-Analyse versucht man Stellen in der Anwendung zu entdecken, die ein großes Risiko für zukünftige Änderungen darstellen können. Dafür gibt es einige kostenpflichtige Werkzeuge für eine statische Code-Analyse, die wirklich gute Resultate erzielen. Da es aber auf dieser Welt noch reichlich Open-Source gibt, habe ich mich mal im Internet umgeschaut und mir ein Analyse-Tool bzw. Script selbst gebaut. Dem Script habe ich den Namen „phpanalyze“ gegeben. PhpAnalyze verlangt jedoch ein UNIX System sowie die Installation von ein paar Helferlein-Tools, die von Sebastian Bergman und Manuel Pichler entwickelt worden sind. Diese sind: phploc, phpcpd, pdepend, phpcs. Diese kann man frei herunterladen und installieren. Zudem habe ich einen eigenen custom-line-count erstellt und in phpanalyze mit eingebaut, darauf gehe ich aber später ein. Phpanalyze hat den Vorteil, dass es große Mengen an Quelltext innerhalb kürzester Zeit analysieren kann. Es verbraucht dabei nur wenige Ressourcen und kann beliebig oft ausgeführt werden. Zudem ist es ein Script, das flexibel an die eigene Entwicklungsumgebung und Bedürfnisse angepasst werden kann und soll.
Phpanalyze wird wie folgt auf der Konsole ausgeführt:
php analyze.php --option /path/to/your/php/project/
Hier die möglichen Parameter für die Analyse: –phploc, –phpcpd, –phpcs, –mylc, –pdepend und zuletzt das –all, das alle vorher genannten Optionen auf einen Schlag ausführt.
Nun gehe ich mal genauer auf die Helferlein-Tools ein, die ich im Script verwende.
phploc – Größe eines Projektes bestimmen
Das Tool kann dazu verwendet werden, die Anzahl an Zeilen PHP Code zu bestimmen. Dabei unterscheidet phploc zwischen Kommentaren und richtigem Code. Zusätzlich zählt es die Interfaces, Klassen, die nichtstatischen- und statischen Methoden und die Funktionen. Das alles auch noch in einer relativ kurzen Zeit. Zudem wird damit auch die zyklomatische Komplexität errechnet. Man bekommt auf einen Blick viele Informationen über sein Projekt und kann somit schnell potenzielle Fehler beheben. Was ich sehr gut finde, ist die Aufzählung der statischen Attribute und Methoden, die man am besten vermeiden sollte.
phpcpd – Copy & Paste Detection
Ein Copy & Paste Detector für PHP Code. Installiert wird das ganze via PEAR Installer. Nach einem ersten schnellen Test freut es mich, 0.00% duplizierten Code vorzufinden. Duplizierten Code sollte man eigentlich vermeiden, dass dies jedoch nicht immer möglich ist, ist mir auch bewusst. Einen Nachteil hat es – duplizierter Code ist schwer zu warten. (He he he…)
phpcs – die Schnüffelnase, oder besser bekannt als PHP Code Sniffer
Das Ganze wird ebenfalls via PEAR Installer installiert und dient dazu, dich auf eventuelle Abweichungen zu deinen firmeninternen Coding-Standards aufmerksam zu machen. Viele hängen den phpcs als pre-commit-hoock an dem SVN, so dass du erst commiten kannst, wenn du auch die Coding-Standards erfüllt hast. Hier rate ich, am Anfang nicht so viele Regeln festzulegen, denn es kann auch mal zu viel sein und die Produktivität kann somit spürbar beeinträchtigt werden. Manche Programmierer bekommen anfangs oft einen Frustrations-Anfall, aber da muss man durch. Wenn man gemerkt hat, dass im Durchschnitt alle aus dem Team die Code-Standards gut beherrschen, so kann man erst dann diese noch erweitern oder verschärfen, aber bitte nur im Abstimmung mit dem Team.
mylc – selbst geschriebener Linien-Zähler
Hier handelt es sich um ein etwas angepasstes UNIX-Kommando. Mittels wc werden alle Zeilen zu jeder Datei im Verzeichnis gezählt und ausgegeben. Nun, was haben wir davon? Das ist ganz einfach: so ist es möglich, Klassen aufzuspüren, die sich anhand ihrer Zeilenanzahl deutlich von den anderen Klassen unterscheiden. Da besteht oft der Verdacht, dass diese Klasse eventuell zuviel weiß oder mit zu vielen Dingen beschäftigt ist, und somit schlecht tastbar ist. Oder oft auch doppelten Code hat. Dieser Klasse sollte man Refraktoren und gegebenenfalls die Logik auslagern, und sie eben tastbar machen.
pdepend – oder phpDepend?
Wie Nils Langner in seinem Blog schreibt: „Metriken sind meistens mathematische Funktionen, die ihr auf euren Source Code anwendet und am Ende einen Wert rausbekommt, der etwas über die Qualität eures Quellcodes aussagen soll.“ So ist es auch bei pdepend. Am Ende der Anayse bekommt man auch eine Auswertung. Diese kann als summary-xml, jdepend-chart oder overview-pyramid ausgegeben werden. Ich verwende gerne das jdepend-chart, da ich für mich damit am besten und schnellsten gute Information gewinnen kann. Zu jdepend-chart: Die Distanz bzw. Ausgewogenheit eines Projektes wird zwischen der Instabilität und der Abstraktion im Projekt berechnet.
Nun, was bedeuten die Werte auf der Instability-Achse und der abstraction-Achse? Eine Klasse ist instabil, wenn der Wert zu 1 tendiert, und sagt uns, dass wir hier viele eingehende Abhängigkeiten haben. Eine Komponente ist wiederum als stabil zu bezeichnen, wenn der Wert zu 0 tendiert. Somit haben wir dementsprechend viele ausgehende Abhängigkeiten im Projekt. Nun die abstraction-Achse: wenn hier der Wert zu 0 tendiert, dann haben wir konkrete Methoden und Klassen, also Klassen die genau wissen was sie tun. Wenn der Wert wiederum zu 1 tendiert, haben wir entsprechend mehr abstrakte Methoden und Klassen. Zusätzlich habe ich die Standard Referenz-Werte dazu gepackt, an denen sich pDepend orientiert, um dein Projekt auszuwerten.
Fazit
Erst nun, da ich an dieser Stelle angekommen bin, kommt mir der Gedanke, dass der phpanalyze Script genauso gut im Phing oder Ant umgesetzt werden kann. Eventuell reiche ich euch das mal nach. Wie auch immer, eine Projekt-Bewertung ist immer objektiv! Subjektive oder persönliche Faktoren spielen keine Rolle! Also installiert euch die feinen Helferlein-Tools, spielt mal mit phpanalyse rum und schreibt mir wie es war. Rock…
Mehr zum Download von phpanalyze und Installation der Helferlein-Tools , hier:
http://www.phphatesme.com/blog/tools/pdepend-eine-kurze-einfuhrung/
http://www.phphatesme.com/blog/tools/php-code-sniffer-installation-und-verwendung/
http://www.phphatesme.com/blog/softwaretechnik/copy-and-paste-detection/
http://www.phphatesme.com/blog/allgemein/grose-eines-projektes-bestimmen/
http://phing.info/trac/
http://ant.apache.org/manual/index.html
phpanalyze.php
Hier eine mögliche Ausgabe von phpanalyze:
phpanalyze 1.1.0 by Gjero Krsteski 2010 Uses phploc, phpcpd, pdepend, phpcs and custom-line-count to analyze your PHP-project. YOUR STATISTICS FOR: /my/customized/Project/Translation/Element/ MEASURES THE SIZE OF YOUR PHP PROJECT -------------------------------------------------------------------------------- phploc 1.5.1 by Sebastian Bergmann. Directories: 2 Files: 13 Lines of Code (LOC): 2511 Cyclomatic Complexity / Lines of Code: 0.07 Comment Lines of Code (CLOC): 1184 Non-Comment Lines of Code (NCLOC): 1327 Namespaces: 0 Interfaces: 0 Classes: 13 Abstract: 0 (0.00%) Concrete: 13 (100.00%) Average Class Length (NCLOC): 122 Methods: 81 Scope: Non-Static: 80 (98.77%) Static: 1 (1.23%) Visibility: Public: 45 (55.56%) Non-Public: 36 (44.44%) Average Method Length (NCLOC): 19 Cyclomatic Complexity / Number of Methods: 2.15 Anonymous Functions: 0 Functions: 0 Constants: 12 Global constants: 0 Class constants: 12 CHECKS DUPLICATED LINES AT YOUR PHP PROJECT -------------------------------------------------------------------------------- phpcpd 1.3.2 by Sebastian Bergmann. 0.00% duplicated lines out of 2511 total lines of code. Time: 0 seconds, Memory: 5.75Mb CHECKS Brainbits CODING STANDARD AT YOUR PHP PROJECT FILE: ...cal/my/customized/Project/Translation/Element/Difference/Facade.php -------------------------------------------------------------------------------- FOUND 0 ERROR(S) AND 3 WARNING(S) AFFECTING 3 LINE(S) -------------------------------------------------------------------------------- 95 | WARNING | Line exceeds 100 characters; contains 102 characters 154 | WARNING | Line exceeds 100 characters; contains 119 characters 181 | WARNING | Line exceeds 100 characters; contains 105 characters -------------------------------------------------------------------------------- FILE: ...al/my/customized/Project/Translation/Element/Difference/Manager.php -------------------------------------------------------------------------------- FOUND 0 ERROR(S) AND 2 WARNING(S) AFFECTING 2 LINE(S) -------------------------------------------------------------------------------- 109 | WARNING | Line exceeds 100 characters; contains 103 characters 141 | WARNING | Line exceeds 100 characters; contains 103 characters -------------------------------------------------------------------------------- CHECKS LINES-COUNT AT YOUR PHP PROJECT -------------------------------------------------------------------------------- 51 /my/customized/Project/Translation/Element/DataIterator.php 344 /my/customized/Project/Translation/Element/Data.php 191 /my/customized/Project/Translation/Element/Difference/Model.php 322 /my/customized/Project/Translation/Element/Difference/Facade.php 167 /my/customized/Project/Translation/Element/Difference/Manager.php 92 /my/customized/Project/Translation/Element/History.php 94 /my/customized/Project/Translation/Element/Lock.php 50 /my/customized/Project/Translation/Element/Message.php 156 /my/customized/Project/Translation/Element/Word/Convention.php 249 /my/customized/Project/Translation/Element/Word/Import.php 311 /my/customized/Project/Translation/Element/Word/ImportFacade.php 281 /my/customized/Project/Translation/Element/Word/ExportFacade.php 203 /my/customized/Project/Translation/Element/Word/Export.php 2511 insgesamt STATIC CODE ANALYSIS OF YOUR PHP PROJECT -------------------------------------------------------------------------------- PHP_Depend 0.9.19 by Manuel Pichler Parsing source files: ............. 13 Executing CyclomaticComplexity-Analyzer: ........ 168 Executing ClassLevel-Analyzer: ....... 155 Executing CodeRank-Analyzer: ...................... 445 Executing Coupling-Analyzer: ........ 168 Executing Dependency-Analyzer: .... 96 Executing Hierarchy-Analyzer: ....... 155 Executing Inheritance-Analyzer: 15 Executing NPathComplexity-Analyzer: ........ 168 Executing NodeCount-Analyzer: .... 96 Executing NodeLoc-Analyzer: ..... 109 Generating pdepend log files, this may take a moment. Time: 00:03; Memory: 25.75Mb SEE SUMMARY.XML AT: /var/www/my/customized/Project/Translation-Element-summary.xml SEE JDEPEND.SVG AT: /var/www/my/customized/Project/Translation-Element-jdepend.svg SEE PYRAMID.SVG AT: /var/www/my/customized/Project/Translation-Element-pyramid.svg REFERENCE VALUES -------------------------------------------------------------------------------- Metric Low Average High CYCLO/LOC 0.16 0.20 0.24 LOC/NOM 7 10 13 NOM/NOC 4 7 10 NOC/NOP 6 17 26 CALLS/NOM 2.01 2.62 3.2 FANOUT/CALLS 0.56 0.62 0.68 ANDC 0.25 0.41 0.57 AHH 0.09 0.21 0.32 --------------------------------------------------------------------------------
Great site. A lot of useful information here. I’m sending it to some friends!
If you could e-mail me with a few suggestions on just how you made your blog look this excellent, I would be grateful.
Do you people have a facebook fan page? I looked for one on twitter but could not discover one, I would really like to become a fan!
It’s really a nice and helpful piece of information. I’m glad that you shared this helpful info with us. Please keep us informed like this. Thanks for sharing.