> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# PHP AST

> De basis van de PHP AST (abstract syntax tree), de plaats van de interne AST van PHP en praktische patronen voor code-analyse en -transformatie met nikic/PHP-Parser.

## 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".

```mermaid theme={null}
graph TD
    A["<?php<br>echo add(1, 2);"] --> B["Stmt\\Expression"]
    B --> C["Expr\\FuncCall: add"]
    C --> D["Arg: 1"]
    C --> E["Arg: 2"]
```

## 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 -r` uitvoert, 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

Kortom: als je denkt "ik wil code bewerken via een AST", is het praktisch om niet de interne runtime-AST van PHP te gebruiken, maar een AST-library die je in userland kunt gebruiken.

## Het nikic/PHP-Parser-package

[nikic/PHP-Parser](https://github.com/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

```bash theme={null}
composer require nikic/php-parser
```

### Een basisvoorbeeld van parsen (code omzetten naar een AST)

```php theme={null}
<?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;
}
```

### De AST doorlopen en wijzigen met het NodeVisitor-patroon

```php theme={null}
<?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);
```

Als je van `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

```php theme={null}
<?php

use PhpParser\PrettyPrinter;

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

echo $newCode;
```

Met deze flow transformeer je niet "code als string", maar "code als syntaxisboom".

## Gebruiksvoorbeeld in Laravel/Chisel

[laravel/chisel](/nl/blog/chisel-introduction) is een library om starter kits achteraf uit te dunnen. In de `composer.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:

1. De code parsen met `ParserFactory::createForNewestSupportedVersion()`
2. Meerdere visitors (zoals `RemoveImportVisitor`) toevoegen aan een `NodeTraverser` en transformeren
3. Terugschrijven met `printFormatPreserving()` van `PhpParser\PrettyPrinter\Standard`, met behoud van de oorspronkelijke opmaak

Dankzij dit ontwerp kunnen `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 van `nikic/php-parser` — Parser, Visitor en Pretty Printer — uit in een kleine CLI.


## Related topics

- [Laravel Chisel — een bibliotheek voor post-installatiescripts van starter kits](/nl/blog/chisel-introduction.md)
- [PHP FFI](/nl/advanced/ffi.md)
- [PHP-attributes](/nl/advanced/php-attributes.md)
- [VOICEVOX Core for PHP](/nl/packages/voicevox-core-php/index.md)
- [PHP Reflection API](/nl/advanced/php-reflection.md)
