淘先锋技术网

首页 1 2 3 4 5 6 7

PHP AST执行,可以说是基于PHP源代码的一种静态分析。通过分析PHP源代码,将其转换成抽象语法树(AST),然后执行操作,返回执行结果。下面主要介绍PHP AST执行的实现原理以及其实际应用。

实现原理:

<?php
$code = 'echo "Hello World!";';
$ast = ast\parse_code($code, $version=50);
$serializedAst = serialize($ast); 
var_dump($serializedAst);
?>

上述代码中,将变量$code中存的PHP代码转化为AST并序列化成字符串,然后通过var_dump将结果打印出来,该结果就是PHP代码的AST的字符串形式。序列化过程中,AST被转化成了一些特定的数据类型,即:Constant、Identifier、UnaryOp、BinaryOp等类型。
针对AST字符串可以做很多实际应用,如代码压缩、代码验证(code linter)、自动修复代码错误等等。

实际应用:

代码压缩:

<?php
$code = 'if (true) {
echo "Hello World!";
}';
$tokens = token_get_all($code, TOKEN_PARSE);
$ast = \ast\parse_code($code, $version = 50);
$bits = \ast\flags\AST_BINARY_OP_BITWISE_OR;
$rewriter = new \AstKit\Rewrite($ast);
$rewriter->apply(function($node) use($bits) {
if ($node instanceof \ast\Node && $node->kind === \ast\AST_BINARY_OP && $node->flags & $bits) {
$node->flags ^= $bits;
}
});
$newCode = $rewriter->getNewCode();
var_dump($newCode);
?>

代码验证:

<?php
$code = 'if ($a = true); { echo "Hello"; }';
$ast = \ast\parse_code($code, $version = 50);
$linter = new \AstLinter\AstLinter();
$linter->registerCheck(new ASTCheck\NoMultiLineString());
$warnings = $linter->lint($ast);
var_dump($warnings);
?>

自动修复代码错误:

<?php
$code = 'if (true) {
$a = 1;
$b = 2;
$c = 3;
}';
$rewrite = new \AstKit\Rewrite(\ast\parse_code($code));
$shouldBreak = true;
$notAssign = new \AstKit\Checker\NoAssign();
$rewrite->apply(function($node) use(&$shouldBreak, $notAssign) {
if ($node instanceof \ast\Node && $node->kind === \ast\AST_IF) {
$children = $node->children;
foreach(end($children)->children as $child) {
if (!$notAssign->check($child)) {
$shouldBreak = false;
break;
}
}
}
});
if ($shouldBreak) {
$childNode = end($rewrite->getNode()->children)->children;
array_pop($childNode);
$rewrite->setNode($childNode[0]);
}
var_dump($rewrite->getNewCode());
?>

总之,PHP AST执行在代码静态分析中有着广泛的应用,能够极大的提高代码的使用率和质量。