Chris@0: PHP Parser Chris@0: ========== Chris@0: Chris@0: [![Build Status](https://travis-ci.org/nikic/PHP-Parser.svg?branch=master)](https://travis-ci.org/nikic/PHP-Parser) [![Coverage Status](https://coveralls.io/repos/github/nikic/PHP-Parser/badge.svg?branch=master)](https://coveralls.io/github/nikic/PHP-Parser?branch=master) Chris@0: Chris@17: This is a PHP 5.2 to PHP 7.3 parser written in PHP. Its purpose is to simplify static code analysis and Chris@0: manipulation. Chris@0: Chris@17: [**Documentation for version 4.x**][doc_master] (stable; for running on PHP >= 7.0; for parsing PHP 5.2 to PHP 7.3). Chris@0: Chris@17: [Documentation for version 3.x][doc_3_x] (unsupported; for running on PHP >= 5.5; for parsing PHP 5.2 to PHP 7.2). Chris@0: Chris@13: Features Chris@13: -------- Chris@0: Chris@13: The main features provided by this library are: Chris@0: Chris@13: * Parsing PHP 5 and PHP 7 code into an abstract syntax tree (AST). Chris@13: * Invalid code can be parsed into a partial AST. Chris@13: * The AST contains accurate location information. Chris@13: * Dumping the AST in human-readable form. Chris@13: * Converting an AST back to PHP code. Chris@13: * Experimental: Formatting can be preserved for partially changed ASTs. Chris@13: * Infrastructure to traverse and modify ASTs. Chris@13: * Resolution of namespaced names. Chris@13: * Evaluation of constant expressions. Chris@13: * Builders to simplify AST construction for code generation. Chris@13: * Converting an AST into JSON and back. Chris@13: Chris@13: Quick Start Chris@13: ----------- Chris@13: Chris@13: Install the library using [composer](https://getcomposer.org): Chris@13: Chris@13: php composer.phar require nikic/php-parser Chris@13: Chris@13: Parse some PHP code into an AST and dump the result in human-readable form: Chris@0: Chris@0: ```php Chris@0: create(ParserFactory::PREFER_PHP7); Chris@13: try { Chris@13: $ast = $parser->parse($code); Chris@13: } catch (Error $error) { Chris@13: echo "Parse error: {$error->getMessage()}\n"; Chris@13: return; Chris@13: } Chris@13: Chris@13: $dumper = new NodeDumper; Chris@13: echo $dumper->dump($ast) . "\n"; Chris@0: ``` Chris@0: Chris@13: This dumps an AST looking something like this: Chris@0: Chris@13: ``` Chris@0: array( Chris@13: 0: Stmt_Function( Chris@13: byRef: false Chris@13: name: Identifier( Chris@13: name: test Chris@13: ) Chris@13: params: array( Chris@13: 0: Param( Chris@13: type: null Chris@13: byRef: false Chris@13: variadic: false Chris@13: var: Expr_Variable( Chris@13: name: foo Chris@13: ) Chris@13: default: null Chris@0: ) Chris@0: ) Chris@13: returnType: null Chris@13: stmts: array( Chris@13: 0: Stmt_Expression( Chris@13: expr: Expr_FuncCall( Chris@13: name: Name( Chris@13: parts: array( Chris@13: 0: var_dump Chris@13: ) Chris@0: ) Chris@13: args: array( Chris@13: 0: Arg( Chris@13: value: Expr_Variable( Chris@13: name: foo Chris@13: ) Chris@13: byRef: false Chris@13: unpack: false Chris@13: ) Chris@0: ) Chris@0: ) Chris@0: ) Chris@0: ) Chris@0: ) Chris@0: ) Chris@0: ``` Chris@0: Chris@13: Let's traverse the AST and perform some kind of modification. For example, drop all function bodies: Chris@0: Chris@13: ```php Chris@13: use PhpParser\Node; Chris@13: use PhpParser\Node\Stmt\Function_; Chris@13: use PhpParser\NodeTraverser; Chris@13: use PhpParser\NodeVisitorAbstract; Chris@0: Chris@13: $traverser = new NodeTraverser(); Chris@13: $traverser->addVisitor(new class extends NodeVisitorAbstract { Chris@13: public function enterNode(Node $node) { Chris@13: if ($node instanceof Function_) { Chris@13: // Clean out the function body Chris@13: $node->stmts = []; Chris@13: } Chris@13: } Chris@13: }); Chris@0: Chris@13: $ast = $traverser->traverse($ast); Chris@13: echo $dumper->dump($ast) . "\n"; Chris@13: ``` Chris@0: Chris@13: This gives us an AST where the `Function_::$stmts` are empty: Chris@13: Chris@13: ``` Chris@13: array( Chris@13: 0: Stmt_Function( Chris@13: byRef: false Chris@13: name: Identifier( Chris@13: name: test Chris@13: ) Chris@13: params: array( Chris@13: 0: Param( Chris@13: type: null Chris@13: byRef: false Chris@13: variadic: false Chris@13: var: Expr_Variable( Chris@13: name: foo Chris@13: ) Chris@13: default: null Chris@13: ) Chris@13: ) Chris@13: returnType: null Chris@13: stmts: array( Chris@13: ) Chris@13: ) Chris@13: ) Chris@13: ``` Chris@13: Chris@13: Finally, we can convert the new AST back to PHP code: Chris@13: Chris@13: ```php Chris@13: use PhpParser\PrettyPrinter; Chris@13: Chris@13: $prettyPrinter = new PrettyPrinter\Standard; Chris@13: echo $prettyPrinter->prettyPrintFile($ast); Chris@13: ``` Chris@13: Chris@13: This gives us our original code, minus the `var_dump()` call inside the function: Chris@13: Chris@13: ```php Chris@13: