PHP Parser(PHP 解析器)
这是一个用 PHP 编写的 PHP 解析器。其目的是简化静态代码分析和操作。
版本 5.x 的文档(当前;用于在 PHP >= 7.4 上运行;用于解析 PHP 7.0 至 PHP 8.3,对 PHP 5.x 的解析支持有限)。
版本 4.x 的文档 (支持;用于在 PHP >= 7.0 上运行;用于解析 PHP 5.2 至 PHP 8.3).
特性
该库提供的主要功能是:
- 将 PHP 7 和 PHP 8 代码解析为抽象语法树(AST)。
- 无效的代码可以解析为部分 AST。
- AST 包含准确的位置信息。
- 以人类可读的形式转储 AST。
- 将 AST 转换回 PHP 代码。
- 实验性:可以保留部分更改的 AST 的格式。
- 遍历和修改 AST 的基础结构。
- 命名空间名称的解析。
- 常量表达式的评估。
- 简化 AST 构建的代码生成器。
- 将 AST 转换为 JSON 并返回。
快速开始
使用composer安装库:
php composer.phar require nikic/php-parser
将一些 PHP 代码解析为 AST 并以人类可读的形式转储结果:
<?php
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";
这将转储一个看起来像这样的 AST:
array(
0: Stmt_Function(
byRef: false
name: Identifier(
name: test
)
params: array(
0: Param(
type: null
byRef: false
variadic: false
var: Expr_Variable(
name: foo
)
default: null
)
)
returnType: null
stmts: array(
0: Stmt_Expression(
expr: Expr_FuncCall(
name: Name(
parts: array(
0: var_dump
)
)
args: array(
0: Arg(
value: Expr_Variable(
name: foo
)
byRef: false
unpack: false
)
)
)
)
)
)
)
让我们遍历 AST 并执行某种修改。 例如,删除所有功能体:
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";
这为我们提供了一个 AST,其中 Function_::$stmts 为空:
array(
0: Stmt_Function(
byRef: false
name: Identifier(
name: test
)
params: array(
0: Param(
type: null
byRef: false
variadic: false
var: Expr_Variable(
name: foo
)
default: null
)
)
returnType: null
stmts: array(
)
)
)
最后,我们可以将新的 AST 转换回 PHP 代码:
use PhpParser\PrettyPrinter; $prettyPrinter = new PrettyPrinter\Standard; echo $prettyPrinter->prettyPrintFile($ast);
这给出了我们的原始代码,减去了函数内部的 var_dump() 调用:
<?php
function test($foo)
{
}
文档
组件文档:
- Walking the AST
- Node visitors
- Modifying the AST from a visitor
- Short-circuiting traversals
- Interleaved visitors
- Simple node finding API
- Parent and sibling references
- Name resolution
- Name resolver options
- Name resolution context
- Pretty printing
- Converting AST back to PHP code
- Customizing formatting
- Formatting-preserving code transformations
- AST builders
- Fluent builders for AST nodes
- Lexer
- Lexer options
- Token and file positions for nodes
- Custom attributes
- Error handling
- Column information for errors
- Error recovery (parsing of syntactically incorrect code)
- Constant expression evaluation
- Evaluating constant/property/etc initializers
- Handling errors and unsupported expressions
- JSON representation
- JSON encoding and decoding of ASTs
- Performance
- Disabling XDebug
- Reusing objects
- Garbage collection impact
- Frequently asked questions
- Parent and sibling references
(The first version translated by vz on 2020.07.26)