2011-05-31 18:01:00 +02:00
|
|
|
PHP Parser
|
|
|
|
==========
|
|
|
|
|
2016-02-20 21:53:08 +01:00
|
|
|
[![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)
|
|
|
|
|
2017-10-03 19:13:20 +02:00
|
|
|
This is a PHP 5.2 to PHP 7.2 parser written in PHP. Its purpose is to simplify static code analysis and
|
2011-05-31 18:01:00 +02:00
|
|
|
manipulation.
|
|
|
|
|
2017-09-02 20:03:10 +02:00
|
|
|
[**Documentation for version 3.x**][doc_3_x] (stable; for running on PHP >= 5.5; for parsing PHP 5.2 to PHP 7.2).
|
2016-10-29 13:37:47 +02:00
|
|
|
|
2017-10-03 19:13:20 +02:00
|
|
|
[Documentation for version 4.x][doc_master] (development; for running on PHP >= 7.0; 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:
|
|
|
|
|
|
|
|
* Parsing PHP 5 and PHP 7 code into an abstract syntax tree (AST).
|
|
|
|
* 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.
|
|
|
|
* Experimental: Formatting can be preserved for partially changed ASTs.
|
|
|
|
* 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;
|
|
|
|
|
|
|
|
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
|
|
|
|
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(
|
|
|
|
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(
|
|
|
|
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(
|
|
|
|
parts: array(
|
|
|
|
0: var_dump
|
|
|
|
)
|
2012-02-21 19:52:49 +01:00
|
|
|
)
|
2017-10-18 18:43:39 +02:00
|
|
|
args: array(
|
|
|
|
0: Arg(
|
|
|
|
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(
|
|
|
|
byRef: false
|
|
|
|
name: Identifier(
|
|
|
|
name: test
|
|
|
|
)
|
|
|
|
params: array(
|
|
|
|
0: Param(
|
|
|
|
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 15:16:29 +02: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 15:16:29 +02: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 15:16:29 +02:00
|
|
|
|
2015-03-10 21:32:21 +01:00
|
|
|
Documentation
|
|
|
|
-------------
|
|
|
|
|
|
|
|
1. [Introduction](doc/0_Introduction.markdown)
|
2015-09-16 15:16:29 +02:00
|
|
|
2. [Usage of basic components](doc/2_Usage_of_basic_components.markdown)
|
|
|
|
3. [Other node tree representations](doc/3_Other_node_tree_representations.markdown)
|
|
|
|
4. [Code generation](doc/4_Code_generation.markdown)
|
2017-04-08 23:27:43 +02:00
|
|
|
5. [Frequently asked questions](doc/5_FAQ.markdown)
|
2015-03-10 21:32:21 +01:00
|
|
|
|
|
|
|
Component documentation:
|
|
|
|
|
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
|
2017-10-03 19:09:27 +02:00
|
|
|
* [Lexer](doc/component/Lexer.markdown)
|
2017-11-10 22:45:27 +01:00
|
|
|
* Lexer options
|
|
|
|
* Token and file positions for nodes
|
|
|
|
* Custom 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)
|
2017-11-10 22:44:06 +01:00
|
|
|
* [Performance](doc/component/Performance.markdown)
|
2017-11-10 22:45:27 +01:00
|
|
|
* Disabling XDebug
|
|
|
|
* Reusing objects
|
|
|
|
* Garbage collection impact
|
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
|
2015-05-02 22:07:16 +02:00
|
|
|
[doc_master]: https://github.com/nikic/PHP-Parser/tree/master/doc
|