1 回答
TA贡献1859条经验 获得超6个赞
这比您提出的其他问题要复杂得多,但是了解如何编写它很有趣。
我已经在代码中添加了注释,但基本上它会分析代码并查找分配(PhpParser\Node\Expr\Assign节点实例)。然后它将它分成左右两部分,并递归地提取两部分中的任何变量。
该代码允许在表达式的任一侧嵌套变量,我更改了示例代码以提供一些更广泛的示例。
代码中的注释(假定了解解析器如何与节点等一起工作)...
$traverser = new NodeTraverser;
class ExtractVars extends NodeVisitorAbstract {
private $prettyPrinter = null;
private $variables = [];
private $expressions = [];
public function __construct() {
$this->prettyPrinter = new PhpParser\PrettyPrinter\Standard;
}
public function leaveNode(Node $node) {
if ( $node instanceof PhpParser\Node\Expr\Assign ) {
$assignVars = $this->extractVarRefs ( $node->var );
// Get string of what assigned to actually is
$assign = $this->prettyPrinter->prettyPrintExpr($node->var);
// Store the variables associated with the left hand side
$this->expressions[$assign]["to"] = $assignVars;
// Store variables from right
$this->expressions[$assign][] = $this->extractVarRefs ( $node->expr );
}
}
private function extractVarRefs ( Node $node ) : array {
$variableList = [];
// If it's a variable, store the name
if ( $node instanceof PhpParser\Node\Expr\Variable ) {
$variable = $this->prettyPrinter->prettyPrintExpr($node);
$this->variables[] = $variable;
$variableList[] = $variable;
}
// Look for any further variables in the node
foreach ( $node->getSubNodeNames() as $newNodeName ) {
$newNode = $node->$newNodeName;
if ( $newNode instanceof Node && $newNode->getSubNodeNames()) {
// Recursive call to extract variables
$toAdd = $this->extractVarRefs ( $newNode );
// Add new list to current list
$variableList = array_merge($variableList, $toAdd);
}
}
return $variableList;
}
public function getVariables() : array {
return array_unique($this->variables);
}
public function getExpressions() : array {
return $this->expressions;
}
}
$varExtract = new ExtractVars();
$traverser->addVisitor ($varExtract);
$traverser->traverse($ast);
print_r($varExtract->getVariables());
print_r($varExtract->getExpressions());
其中给出了变量列表...
Array
(
[0] => $_POST
[1] => $b
[3] => $new
[4] => $nonexist
)
表达式列表为
Array
(
[$_POST[$b]] => Array
(
[to] => Array
(
[0] => $_POST
[1] => $b
)
[0] => Array
(
[0] => $_POST
)
)
[$new] => Array
(
[to] => Array
(
[0] => $new
)
[0] => Array
(
[0] => $nonexist
)
[1] => Array
(
[0] => $_POST
[1] => $b
)
)
)
请注意,[to]数组的元素包含 . 左侧涉及的所有变量=。
- 1 回答
- 0 关注
- 147 浏览
添加回答
举报