Experimentelle Analysen von PHP Code für Enthusiasten

Während ich im vorhergehenden Artikel die „Standardtools“ für die Analyse von PHP verwendet habe, möchte ich hier einen Schritt weitergehen. Wenn ich schon meine Programme analysieren lasse, dann richtig :)! Darum hier ein paar nicht-standard Analysetools für PHP, die ich als eher experimentell bezeichnen würde:

  • doxygen
  • phuml
  • php-lint
  • PHP Callgraph

Doxygen statt phpDocumentor

Ich hab grössten Respekt vor dem phpDocumentor Projekt, aber Doxygen hat ein paar Vorteile:

  • Es kann mit nicht-UTF-8-Dateien umgehen.
  • Es ist schneller.
  • Es kommt mit anonymen Funktionen klar.

Leider ist es nicht zu 100% kompatibel zu phpDocumentor. Es hat Mühe mit Kurzbeschreibungen, Parametern, etc.

Die Inbetriebnahme ist ganz einfach: mittels doxygen -g CONFIGNAME wird eine Standardkonfiguration erstellt, die man am Besten sofort editiert und mindestens folgende Dinge anpasst:

Name des Projekts
PROJECT_NAME = Simple PHP Fixtures System
Ausgabeverzeichnis
OUTPUT_DIRECTORY = statistics/html/doc/api/
Auch private Members anzeigen
EXTRACT_PRIVATE = YES
Verzeichnis des zu dokumentierenden Codes
INPUT = ../code
SVN-Verzeichnisse nicht durchsuchen
EXCLUDE_PATTERNS = */.svn/*
Automatische Kurzbeschreibungen
JAVADOC_AUTOBRIEF = YES

Wird der Dokumentationsvorgang nun mittels doxygen CONFIGNAME gestartet, so geht es unglaublich schnell und man hat eine peppige API-Dokumentation:

Das Ant-Target aus dem letzten Artikel kann folgendermassen umgeschrieben werden:

    <target name="doc-phpdoc">
        <exec executable="doxygen" failonerror="false" dir="${basedir}">
            <arg value="${doxygenconf}"/>
        </exec>
    </target>

doxygenconf muss natürlich noch in der properties-Datei mit dem Pfad der Configdatei gefüllt werden.

Phuml

phUML erzeugt – nicht ganz standardkonforme – UML-Diagramme aus PHP-Code. Je nach Veranlagung sieht man ziemlich schnell, wenn etwas in der Struktur schief gelaufen ist. Wurde das Phuml-SVN ausgecheckt, kann mit dem Kommando php phuml -r -graphviz -createAssociations true -neato uml.png ein Diagramm erstellt werden. Möchte man lieber ein anderes Format als ng, so kann das in der Datei phuml/src/classes/processor/neato.php, Funktion execute() auf der Zeile mit 'neato -Tpng -o [...] umgestellt werden. Zur Verfügung stehen viele: ps, pdf, svg, gif, … man neato gibt gerne Auskunft.

UML-Diagramm

PHP-Lint

Die Lints haben eine lange Geschichte in der Programmierung, sie sind sozusagen das Werkzeug für statische Code-Analyse. Im Gegensatz zu einigen Anderen bin ich der Meinung, dass php -l ein Syntaxcheck und damit kein Lint ist. Für PHP heisst das Teil PHPLint und ist ebenso kritisch wie die Lints für andere Sprachen. Es macht Gebrauch von PHP-Doc Kommentaren für erweiterte Analyseinformationen. Leider kann PHP-Lint (im Moment) nicht mit Closures umgehen und etwas speziell ist, dass die verwendeten PHP-Module zu Beginn der zu untersuchenden Dateien aufgeführt werden müssen:

/*.
    require_module 'standard';
    require_module 'pdo';
    require_module 'session';
.*/

Ebenfalls kann man ihm mit expliziten castings wie (string) oder etwas hässlichen Kommentaren /*. string .*/ im Code bei der Arbeit unterstützen.

Die Installation läuft folgendermassen:

  1. Download der entsprechenden Version (pure-c für Linux).
  2. Entpacken des Tars und eventuell kompilieren.
  3. Ein eigenes Verzeichnis erstellen (bspw. /opt/php/phplint
  4. Das Verzeichnis modules und die Datei src/phplint in das erstellte Verzeichnis kopieren.
  5. phplint starten mittels: /opt/php/phplint/phplint --modules-path /opt/php/phplint/modules/
  6. Nun sollten ganz viele Fehler ausgegeben werden.

    ...
    /home/skaldrom/svn/syncic/SimplePHPFixturesSystem/trunk/code/SimpleFixtures.php:136: Warning: comparing (mixed) == (mixed): `mixed' type cannot be compared. Hint: check and convert mixed values to the appropriate type, or consider to use strict comparison operators === or !== if it is the case.
    /home/skaldrom/svn/syncic/SimplePHPFixturesSystem/trunk/code/SimpleFixtures.php:139: notice: 'continue EXPR': unadvised programming practice
    /home/skaldrom/svn/syncic/SimplePHPFixturesSystem/trunk/code/SimpleFixtures.php:135: notice: variable `$foreignkey' assigned but never used
    /home/skaldrom/svn/syncic/SimplePHPFixturesSystem/trunk/code/SimpleFixtures.php:126: notice: variable `$candidateData' assigned but never used
    /home/skaldrom/svn/syncic/SimplePHPFixturesSystem/trunk/code/SimpleFixtures.php:170: Warning: comparing (mixed) == (string): `mixed' type cannot be compared. Hint: check and convert mixed values to the appropriate type, or consider to use strict comparison operators === or !== if it is the case.
    /home/skaldrom/svn/syncic/SimplePHPFixturesSystem/trunk/code/SimpleFixtures.php:176: Warning: applying the `[]' operator to array of undefined index type
    /home/skaldrom/svn/syncic/SimplePHPFixturesSystem/trunk/code/SimpleFixtures.php:178: ERROR: method `SimpleFixtures::_untangleTree()': expected return type void, found expression of type array[]string
    /home/skaldrom/svn/syncic/SimplePHPFixturesSystem/trunk/code/SimpleFixtures.php:183: Warning: calling `SimpleFixtures::_untangleTree()' declared in line 160, argument no. 1: found type `mixed', required type `string'
    /home/skaldrom/svn/syncic/SimplePHPFixturesSystem/trunk/code/SimpleFixtures.php:188: Warning: applying the `[]' operator to array of undefined index type
    ...

Damit phplint auch in Jenkins genutzt werden kann, habe ich einen kleinen Wrapper geschrieben, der die Ausgabe in JSLint-XML umwandelt. Damit kann diese Ausgabe komfortabel beim Violations-Modul eingebaut werden. Die PHP-Datei muss im selben Verzeichnis wie phplint platziert werden und geht davon aus, dass modules ein Unterverzeichnis ist. Download hier: phplint.php.

PHPLint in Jenkins

Ein grosses Problem gibt es in Netbeans… Wird der PHP-Code neu formatiert, werden bei den Kommentaren um die Module herum Leerschläge platziert und phplint erkennt sie nimmer. Sehr nervig, echt…

PHP Call Graph

php CallGraph ist ein wunderbares Stück Software, dass einige bestehende Libraries clever vereint. Es produziert Aufrufgraphen einer bestehenden Software, die ziemlich effizient mit dem intuitiven Plan des Entwicklers verglichen werden können. Schöne Beispiele gibt es auf der Website.

phpCallGraph verlässt sich unter Anderem auf phpDoc-Kommentare. Die sollten also entweder gar nicht oder einigermassen gescheit ausgefüllt werden. Sollte es trotzdem ein Problem geben, so kann zum Debuggen die Zeile 517 und 518 in der Datei lib/instantsvc/components/CodeAnalyzer/src/code_analyzer.php entkommentiert werden:

echo '$filename = ', var_export($filename, true), ";\n";
echo '$result   = ', var_export($result, true), ";\n";

Ich habe einen Patch eingereicht, der einige Warnings entfernt und eine „ignore“ Option hinzufügt, der alsbald angewendet wird.

Da war ich zu blöd dafür

Für php-ast und php-sat war ich leider zu blöd. Ich hatte weder Nerven noch Zeit für die Build-Prozedur und die Projekte scheinen auch seit längerem still zu liegen. Die Ideen wären aber grundsätzlich interessant.

2 Gedanken zu „Experimentelle Analysen von PHP Code für Enthusiasten

  1. Hi,

    schonmal versucht PHPLint in Netbeans zu implementieren?
    Wäre nämlich schick das dort zu verwenden.

    Grüße
    Chris

  2. Das wäre eine wirklich gute Sache..! Auch das PMD für PHP (und btw redmine) fehlt so ziemlich!

    Etwas besser wird es, wenn man bei Tools → Options → Editor → PHP alle Häckchen setzt…

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.