2011-05-31 18:01:00 +02:00
PHP Parser
==========
2020-12-20 10:58:16 +01:00
[![Coverage Status ](https://coveralls.io/repos/github/nikic/PHP-Parser/badge.svg?branch=master )](https://coveralls.io/github/nikic/PHP-Parser?branch=master)
2016-02-20 21:53:08 +01:00
2022-09-04 16:16:25 +02:00
This is a PHP parser written in PHP. Its purpose is to simplify static code analysis and
2011-05-31 18:01:00 +02:00
manipulation.
2023-08-16 20:58:35 +02:00
[Documentation for version 5.x][doc_master] (in development; for running on PHP >= 7.4; for parsing PHP 7.0 to PHP 8.3, with limited support for parsing PHP 5.x).
2022-06-12 21:18:11 +02:00
2023-09-17 15:28:40 +02:00
[**Documentation for version 4.x**][doc_4_x] (stable; for running on PHP >= 7.0; for parsing PHP 5.2 to PHP 8.3).
2016-10-29 13:37:47 +02:00
2018-07-22 21:42:51 +02:00
[Documentation for version 3.x][doc_3_x] (unsupported; for running on PHP >= 5.5; for parsing PHP 5.2 to PHP 7.2).
2014-09-12 14:40:17 +02:00
2017-10-18 18:43:39 +02:00
Features
--------
The main features provided by this library are:
2022-09-04 16:16:25 +02:00
* Parsing PHP 7, and PHP 8 code into an abstract syntax tree (AST).
2017-10-18 18:43:39 +02:00
* Invalid code can be parsed into a partial AST.
* The AST contains accurate location information.
* Dumping the AST in human-readable form.
* Converting an AST back to PHP code.
2022-09-04 16:16:25 +02:00
* Formatting can be preserved for partially changed ASTs.
2017-10-18 18:43:39 +02:00
* Infrastructure to traverse and modify ASTs.
* Resolution of namespaced names.
* Evaluation of constant expressions.
* Builders to simplify AST construction for code generation.
* Converting an AST into JSON and back.
2012-02-21 19:52:49 +01:00
2017-10-18 18:43:39 +02:00
Quick Start
-----------
Install the library using [composer ](https://getcomposer.org ):
php composer.phar require nikic/php-parser
Parse some PHP code into an AST and dump the result in human-readable form:
2012-02-21 19:52:49 +01:00
```php
< ?php
2017-10-18 18:43:39 +02:00
use PhpParser\Error;
use PhpParser\NodeDumper;
use PhpParser\ParserFactory;
$code = < < < 'CODE'
< ?php
function test($foo)
{
var_dump($foo);
}
CODE;
2022-09-04 16:16:25 +02:00
$parser = (new ParserFactory())->createForNewestSupportedVersion();
2017-10-18 18:43:39 +02:00
try {
$ast = $parser->parse($code);
} catch (Error $error) {
echo "Parse error: {$error->getMessage()}\n";
return;
}
$dumper = new NodeDumper;
echo $dumper->dump($ast) . "\n";
2012-02-21 19:52:49 +01:00
```
2017-10-18 18:43:39 +02:00
This dumps an AST looking something like this:
2012-02-21 19:52:49 +01:00
2017-10-18 18:43:39 +02:00
```
2012-02-21 19:52:49 +01:00
array(
2017-10-18 18:43:39 +02:00
0: Stmt_Function(
2023-05-27 21:34:21 +02:00
attrGroups: array(
)
2017-10-18 18:43:39 +02:00
byRef: false
name: Identifier(
name: test
2012-02-21 19:52:49 +01:00
)
2017-10-18 18:43:39 +02:00
params: array(
0: Param(
2023-05-27 21:34:21 +02:00
attrGroups: array(
)
flags: 0
2017-10-18 18:43:39 +02:00
type: null
2012-02-21 19:52:49 +01:00
byRef: false
2017-10-18 18:43:39 +02:00
variadic: false
var: Expr_Variable(
name: foo
)
default: null
2012-02-21 19:52:49 +01:00
)
2017-10-18 18:43:39 +02:00
)
returnType: null
stmts: array(
0: Stmt_Expression(
expr: Expr_FuncCall(
name: Name(
2023-05-27 21:34:21 +02:00
name: var_dump
2012-02-21 19:52:49 +01:00
)
2017-10-18 18:43:39 +02:00
args: array(
0: Arg(
2023-05-27 21:34:21 +02:00
name: null
2017-10-18 18:43:39 +02:00
value: Expr_Variable(
name: foo
)
byRef: false
unpack: false
)
2012-02-21 19:52:49 +01:00
)
)
2017-10-18 18:43:39 +02:00
)
)
)
)
```
Let's traverse the AST and perform some kind of modification. For example, drop all function bodies:
```php
use PhpParser\Node;
use PhpParser\Node\Stmt\Function_;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitorAbstract;
$traverser = new NodeTraverser();
$traverser->addVisitor(new class extends NodeVisitorAbstract {
public function enterNode(Node $node) {
if ($node instanceof Function_) {
// Clean out the function body
$node->stmts = [];
}
}
});
$ast = $traverser->traverse($ast);
echo $dumper->dump($ast) . "\n";
```
This gives us an AST where the `Function_::$stmts` are empty:
```
array(
0: Stmt_Function(
2023-05-27 21:34:21 +02:00
attrGroups: array(
)
2017-10-18 18:43:39 +02:00
byRef: false
name: Identifier(
name: test
)
params: array(
0: Param(
2023-05-27 21:34:21 +02:00
attrGroups: array(
)
2017-10-18 18:43:39 +02:00
type: null
2012-02-21 19:52:49 +01:00
byRef: false
2017-10-18 18:43:39 +02:00
variadic: false
var: Expr_Variable(
name: foo
)
default: null
2012-02-21 19:52:49 +01:00
)
)
2017-10-18 18:43:39 +02:00
returnType: null
stmts: array(
)
2012-02-21 19:52:49 +01:00
)
)
```
2017-10-18 18:43:39 +02:00
Finally, we can convert the new AST back to PHP code:
2012-02-21 19:52:49 +01:00
2017-10-18 18:43:39 +02:00
```php
use PhpParser\PrettyPrinter;
2012-02-21 19:52:49 +01:00
2017-10-18 18:43:39 +02:00
$prettyPrinter = new PrettyPrinter\Standard;
echo $prettyPrinter->prettyPrintFile($ast);
```
2015-09-16 22:16:29 +09:00
2017-10-18 18:43:39 +02:00
This gives us our original code, minus the `var_dump()` call inside the function:
2015-09-16 22:16:29 +09:00
2017-10-18 18:43:39 +02:00
```php
< ?php
function test($foo)
{
}
```
For a more comprehensive introduction, see the documentation.
2015-09-16 22:16:29 +09:00
2015-03-10 21:32:21 +01:00
Documentation
-------------
1. [Introduction ](doc/0_Introduction.markdown )
2015-09-16 22:16:29 +09:00
2. [Usage of basic components ](doc/2_Usage_of_basic_components.markdown )
2015-03-10 21:32:21 +01:00
Component documentation:
2018-02-28 21:14:04 +01:00
* [Walking the AST ](doc/component/Walking_the_AST.markdown )
2018-02-28 21:00:42 +01:00
* Node visitors
* Modifying the AST from a visitor
* Short-circuiting traversals
* Interleaved visitors
* Simple node finding API
* Parent and sibling references
2017-10-03 19:09:27 +02:00
* [Name resolution ](doc/component/Name_resolution.markdown )
2017-11-10 22:45:27 +01:00
* Name resolver options
* Name resolution context
2017-10-03 19:09:27 +02:00
* [Pretty printing ](doc/component/Pretty_printing.markdown )
2017-11-10 22:45:27 +01:00
* Converting AST back to PHP code
* Customizing formatting
* Formatting-preserving code transformations
2018-04-07 17:27:00 +02:00
* [AST builders ](doc/component/AST_builders.markdown )
2018-01-27 18:56:21 +01:00
* Fluent builders for AST nodes
2017-10-03 19:09:27 +02:00
* [Lexer ](doc/component/Lexer.markdown )
2023-09-17 20:26:35 +02:00
* Emulation
* Tokens, positions and attributes
2017-10-03 19:09:27 +02:00
* [Error handling ](doc/component/Error_handling.markdown )
2017-11-10 22:45:27 +01:00
* Column information for errors
* Error recovery (parsing of syntactically incorrect code)
2018-04-07 17:27:00 +02:00
* [Constant expression evaluation ](doc/component/Constant_expression_evaluation.markdown )
2018-01-27 17:45:37 +01:00
* Evaluating constant/property/etc initializers
* Handling errors and unsupported expressions
2018-04-07 17:27:00 +02:00
* [JSON representation ](doc/component/JSON_representation.markdown )
2018-02-08 16:21:25 +01:00
* JSON encoding and decoding of ASTs
2017-11-10 22:44:06 +01:00
* [Performance ](doc/component/Performance.markdown )
2021-05-03 20:36:30 -03:00
* Disabling Xdebug
2017-11-10 22:45:27 +01:00
* Reusing objects
* Garbage collection impact
2018-04-07 17:27:00 +02:00
* [Frequently asked questions ](doc/component/FAQ.markdown )
2018-01-27 18:40:22 +01:00
* Parent and sibling references
2011-08-04 18:19:45 +02:00
2017-01-19 20:48:57 +01:00
[doc_3_x]: https://github.com/nikic/PHP-Parser/tree/3.x/doc
2022-06-12 21:18:11 +02:00
[doc_4_x]: https://github.com/nikic/PHP-Parser/tree/4.x/doc
2015-05-02 22:07:16 +02:00
[doc_master]: https://github.com/nikic/PHP-Parser/tree/master/doc