Zum Hauptinhalt springen

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 -r ausgefü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.
Kurz gesagt: Wenn Sie „Code über den AST bearbeiten” wollen, ist es in der Praxis sinnvoll, statt des internen PHP-Laufzeit-AST eine im Userland verwendbare AST-Bibliothek einzusetzen.

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

composer require nikic/php-parser

Beispiel für einfaches Parsen (Code in AST umwandeln)

<?php

use PhpParser\Error;
use PhpParser\ParserFactory;

$code = <<<'CODE'
<?php
function greet(string $name): void {
    echo "Hello, {$name}";
}
CODE;

$parser = (new ParserFactory())->createForNewestSupportedVersion();

try {
    $ast = $parser->parse($code);
} catch (Error $error) {
    echo "Parse error: {$error->getMessage()}\n";
    return;
}

AST mit dem NodeVisitor-Muster traversieren und verändern

<?php

use PhpParser\Node;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitorAbstract;

$traverser = new NodeTraverser();

$traverser->addVisitor(new class extends NodeVisitorAbstract {
    public function leaveNode(Node $node)
    {
        if ($node instanceof Node\Scalar\Int_) {
            return new Node\Scalar\String_((string) $node->value);
        }
    }
});

$modifiedAst = $traverser->traverse($ast);
Wenn Sie von 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

<?php

use PhpParser\PrettyPrinter;

$prettyPrinter = new PrettyPrinter\Standard();
$newCode = $prettyPrinter->prettyPrintFile($modifiedAst);

echo $newCode;
Mit diesem Ablauf machen Sie nicht mehr „Code als Zeichenkette”, sondern „Code als Syntaxbaum” zum Ziel Ihrer Transformationen.

Anwendungsbeispiel: Laravel/Chisel

laravel/chisel ist eine Bibliothek, mit der Sie Starter-Kits nachträglich abschleifen. In der composer.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:
  1. Code mit ParserFactory::createForNewestSupportedVersion() parsen.
  2. Mehrere Visitor (z. B. RemoveImportVisitor) am NodeTraverser registrieren und die Transformation ausführen.
  3. Mit printFormatPreserving() des PhpParser\PrettyPrinter\Standard unter Beibehaltung der ursprünglichen Formatierung zurückschreiben.
Durch dieses Design lassen sich das Entfernen von 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 von nikic/php-parser in einem kleinen CLI aus.
Zuletzt geändert am 13. Juli 2026