nikic/php-parser
Parse PHP code into an Abstract Syntax Tree (AST) for static analysis, manipulation, and code generation. Supports PHP 5.x to 8.4, handles errors gracefully, and preserves formatting during AST-to-code conversion. Easily traverse, modify, and convert ASTs back to PHP, with JSON serialization support...
Start by installing the package via Composer: composer require nikic/php-parser. The library provides three core capabilities: parsing PHP code into an Abstract Syntax Tree (AST), traversing and modifying that AST, and generating PHP code back from AST nodes. The fastest way to begin is:
ParserFactory::createForNewestSupportedVersion() to create a parser tuned to your PHP version.NodeDumper.NodeTraverser with a custom NodeVisitorAbstract to walk and mutate nodes.PrettyPrinter\Standard::prettyPrintFile().The Quick Start in the README contains a complete example showing these steps.
NodeVisitorAbstract to implement analysis (e.g., detecting unused variables) or transformations (e.g., adding return type declarations). Chain multiple visitors via NodeTraverser.PhpParser\Builder namespace to programmatically construct AST nodes (e.g., new Function_('myFunc')->makePublic()->addParam('arg')) instead of instantiating nodes directly.NameResolver when you need to resolve Name nodes (e.g., converting Foo\Bar to Fully\Qualified\Class)—essential for tools that operate on fully qualified names.PrettyPrinter\FormattingPreserver when modifying only specific nodes (e.g., renaming a class), to retain original indentation and comments.NodeDumper::dump() or JsonDecoder/Encoder.For code generation, combine builders with constants evaluation (ConstExprEvaluator) to compute runtime-safe literals in generated code.
ParserFactory::createForHostVersion() (not createForNewestSupportedVersion()) to parse code matching the host PHP version exactly—critical for handling PHP 8.x syntax correctly. The parser version may lag behind PHP’s latest features.ParserFactory::PREFER_PHP7 or enable error recovery to get partial ASTs for invalid code; useful for linters but expect incomplete node lists.flags, attrGroups) or visibility, ensure you use Param::makePrivate(), makeReadonly(), etc., rather than direct assignment—this avoids pretty-print bugs (noted in v5.7, v5.6.x releases).new, instanceof, and unary operators.var_dump() on large ASTs—use NodeDumper instead.instanceof checks can fail if you accidentally compare Name vs Name_FullyQualified nodes—use NameResolver early in your pipeline to normalize names.Name::$parts → Name::getParts()).How can I help you explore Laravel packages today?