Was ist der PHP AST?
Ein AST (Abstract Syntax Tree / abstrakter Syntaxbaum) ist eine Baumstruktur, in die Quellcode nach seiner „semantischen Struktur” zerlegt wird. Wenn Sie Werkzeuge zur Codegenerierung, statischen Analyse oder für automatisches Refactoring bauen, ist der AST fast immer eine unverzichtbare Grundlage. Selbst Transformationen, die als reine String-Ersetzung leicht zerbrechen, lassen sich mit dem AST als syntaktische Einheiten wie „Funktionsaufruf”, „Klassendeklaration” oder „use-Anweisung” sicher behandeln.
Der interne AST von PHP
Ab PHP 7 wandelt die Zend Engine PHP-Code nicht mehr direkt in Opcode um, sondern konvertiert ihn zunächst in einen internen AST und kompiliert danach.- Auch eine mit
php -rausgeführte Einzeiler-Code-Sequenz durchläuft intern dieselbe Compile-Pipeline. - OPcache speichert und wiederverwendet den final erzeugten Opcode im Cache.
- In der normalen Anwendungsentwicklung haben Sie kaum Gelegenheit, diesen internen AST direkt zu manipulieren.
Das Paket nikic/PHP-Parser
nikic/PHP-Parser ist die Standardbibliothek zum Parsen, Traversieren und Neuerzeugen von PHP-Code als AST. In der README und der offiziellen Doku werden die folgenden drei Schritte als Grundmuster beschrieben.Installation
Beispiel für einfaches Parsen (Code in AST umwandeln)
AST mit dem NodeVisitor-Muster traversieren und verändern
NodeVisitorAbstract erben, müssen Sie nur die benötigten Hooks (enterNode / leaveNode) implementieren. Bei komplexen Transformationen bewährt sich das Muster, Informationen in enterNode zu sammeln und in leaveNode zu ersetzen.
Code mit dem Pretty Printer neu erzeugen
Anwendungsbeispiel: Laravel/Chisel
laravel/chisel ist eine Bibliothek, mit der Sie Starter-Kits nachträglich abschleifen. In dercomposer.json wird nikic/php-parser in der 5.x-Reihe als Abhängigkeit eingebunden.
In Chisels Laravel\Chisel\Ast\Source wird die AST-Bearbeitung wie folgt umgesetzt:
- Code mit
ParserFactory::createForNewestSupportedVersion()parsen. - Mehrere Visitor (z. B.
RemoveImportVisitor) amNodeTraverserregistrieren und die Transformation ausführen. - Mit
printFormatPreserving()desPhpParser\PrettyPrinter\Standardunter Beibehaltung der ursprünglichen Formatierung zurückschreiben.
use-Anweisungen, Traits und Interfaces syntaxbasiert und sicher durchführen — nicht per Textersetzung.
Anwendungsfälle
Mit dem AST lässt sich unter anderem folgende Entwicklung erleichtern:- Code-Generierungs-CLIs (nach dem Anlegen eines Gerüsts syntaxbasiert weiterbearbeiten)
- Werkzeuge zur statischen Analyse (Erkennung bestimmter Syntaxstrukturen, Erkennung von Regelverstößen)
- Automatisches Refactoring (halbautomatische Umstellung von APIs oder Umbenennungen)
- Nachbearbeitung von Projektvorlagen (Feature-Entfernung/-Ersetzung wie bei Chisel)
Fazit
Der PHP AST ist keine Funktion, die Sie in der normalen Laravel-Entwicklung jeden Tag brauchen. Wenn Sie jedoch Tools oder Pakete entwickeln, ist der AST eine starke Grundlage für „robuste und reproduzierbare Codeänderungen”. Probieren Sie zunächst die drei Bausteine Parser, Visitor und Pretty Printer vonnikic/php-parser in einem kleinen CLI aus.