Saltar al contenido principal

Qué es el AST de PHP

Un AST (Abstract Syntax Tree / árbol sintáctico abstracto) es una estructura arbórea que descompone el código fuente en «unidades con significado». Cuando construyas una herramienta de generación de código, un analizador estático o un refactorizador automático, el AST es una base prácticamente imprescindible. Transformaciones frágiles con reemplazo de cadenas se pueden manejar con seguridad a nivel sintáctico usando conceptos como «llamada a función», «declaración de clase» o «sentencia use».

El AST interno de PHP

Desde PHP 7, el motor Zend no compila el código PHP directamente a opcodes: primero lo convierte en un AST interno y de ahí compila.
  • Incluso las líneas ejecutadas con php -r pasan internamente por el mismo pipeline de compilación.
  • OPcache guarda en caché los opcodes finalmente generados para reutilizarlos.
  • En el desarrollo normal de aplicaciones, casi nunca manipularás directamente este AST interno.
Es decir, cuando piensas «quiero editar código con AST», lo práctico no es tocar el AST del runtime de PHP, sino usar una librería de AST que puedas manejar desde userland.

El paquete nikic/PHP-Parser

nikic/PHP-Parser es la librería estándar para analizar, recorrer y regenerar código PHP como AST. En su README y en la documentación oficial se explican tres pasos básicos.

Instalación

composer require nikic/php-parser

Ejemplo básico de parseo (código → AST)

<?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;
}

Recorrer y modificar el AST con NodeVisitor

<?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);
Al extender NodeVisitorAbstract, implementas solo los hooks que necesites (enterNode / leaveNode). Para transformaciones complejas, es útil recolectar información en enterNode y sustituir en leaveNode.

Regenerar el código con Pretty Printer

<?php

use PhpParser\PrettyPrinter;

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

echo $newCode;
Con este flujo, el objetivo de la transformación deja de ser «código como cadena» para pasar a ser «código como árbol sintáctico».

Ejemplo de uso en Laravel/Chisel

laravel/chisel es una librería que recorta a posteriori los starter kits. En su composer.json incluye nikic/php-parser en la serie 5.x. En Laravel\Chisel\Ast\Source de Chisel, la edición del AST sigue estos pasos:
  1. Parsea el código con ParserFactory::createForNewestSupportedVersion().
  2. Añade varios visitors (RemoveImportVisitor, etc.) al NodeTraverser para transformarlo.
  3. Con printFormatPreserving() de PhpParser\PrettyPrinter\Standard, lo vuelve a escribir preservando el formato original.
Con este diseño, la eliminación de sentencias use, traits o interfaces se puede hacer de forma sintáctica y segura, en lugar de con reemplazo de texto.

Casos de uso

Con AST puedes abordar más fácilmente desarrollos como:
  • CLIs de generación de código (edición a nivel sintáctico tras crear un scaffold).
  • Herramientas de análisis estático (detección de construcciones específicas o violaciones de reglas).
  • Refactorizaciones automáticas (semi-automatización de migraciones de API o renombrados).
  • Post-procesado de plantillas de proyecto (eliminación o sustitución de funcionalidades, como Chisel).

Resumen

El AST de PHP no es una funcionalidad que uses a diario en el desarrollo típico de aplicaciones Laravel. Sin embargo, si te dedicas al desarrollo de herramientas o paquetes, el AST es una base potente para conseguir «cambios de código robustos y reproducibles». Prueba primero los tres puntos de nikic/php-parser (parser, visitor y pretty printer) en un pequeño CLI.
Última modificación el 13 de julio de 2026