Wat is een PHP AST?
Een AST (Abstract Syntax Tree / abstracte syntaxisboom) is een boomstructuur die broncode opdeelt in “betekenisvolle structuren”. Wanneer je codegeneratietools, statische-analysetools of automatische refactoringtools bouwt, is een AST vrijwel altijd een onmisbare basis. Transformaties die met stringvervanging snel kapotgaan, kun je met een AST veilig uitvoeren per syntactische eenheid, zoals een “function call”, een “class declaration” of een “use statement”.
De interne AST van PHP
De Zend Engine van PHP 7 en later zet PHP-code niet direct om naar opcodes, maar converteert die eerst naar een interne AST en compileert daarna.- Ook een éénregelige code die je met
php -ruitvoert, gaat intern door dezelfde compilatiepipeline - OPcache cachet en hergebruikt de uiteindelijk gegenereerde opcodes
- In gewone appontwikkeling kom je vrijwel nooit in de situatie dat je deze interne AST rechtstreeks manipuleert
Het nikic/PHP-Parser-package
nikic/PHP-Parser is de standaardlibrary om PHP-code als AST te parsen, te doorlopen en opnieuw te genereren. De README en de officiële documentatie beschrijven de volgende drie stappen als basis.Installatie
Een basisvoorbeeld van parsen (code omzetten naar een AST)
De AST doorlopen en wijzigen met het NodeVisitor-patroon
NodeVisitorAbstract erft, hoef je alleen de hooks te implementeren die je nodig hebt (enterNode / leaveNode). Bij complexe transformaties werkt de flow goed waarbij je in enterNode informatie verzamelt en in leaveNode vervangt.
Code opnieuw genereren met de Pretty Printer
Gebruiksvoorbeeld in Laravel/Chisel
laravel/chisel is een library om starter kits achteraf uit te dunnen. In decomposer.json is de 5.x-reeks van nikic/php-parser als dependency opgenomen.
In Laravel\Chisel\Ast\Source van Chisel worden AST-bewerkingen in de volgende stappen uitgevoerd:
- De code parsen met
ParserFactory::createForNewestSupportedVersion() - Meerdere visitors (zoals
RemoveImportVisitor) toevoegen aan eenNodeTraverseren transformeren - Terugschrijven met
printFormatPreserving()vanPhpParser\PrettyPrinter\Standard, met behoud van de oorspronkelijke opmaak
use-statements, traits en interfaces veilig op syntaxisbasis worden verwijderd in plaats van via tekstvervanging.
Use cases
Met een AST wordt dit soort ontwikkeling een stuk makkelijker:- Codegeneratie-CLI’s (na het aanmaken van een sjabloon per syntactische eenheid bewerken)
- Statische-analysetools (specifieke constructies detecteren, regelovertredingen detecteren)
- Automatische refactoring (API-migraties en naamswijzigingen semi-automatiseren)
- Nabewerking van projecttemplates (features verwijderen of vervangen, zoals Chisel doet)
Samenvatting
Een PHP AST is geen functie die je in gewone Laravel-appontwikkeling dagelijks gebruikt. Maar als je tools of packages ontwikkelt, is de AST een krachtige basis voor “robuuste en reproduceerbare codewijzigingen”. Probeer eerst de drie onderdelen vannikic/php-parser — Parser, Visitor en Pretty Printer — uit in een kleine CLI.