0

我正在使用 nikic/PHP-Parser 来解析我的 PHP 代码并从中提取变量的数量。我可以在一个 PHP 文件中做到这一点。

这是代码

<?php
use PhpParser\Error;
use PhpParser\ParserFactory;
use PhpParser\NodeDumper;
use PhpParser\NodeTraverser;
use PhpParser\Node;
use PhpParser\NodeVisitorAbstract;
use PhpParser\PrettyPrinter;

require __DIR__ . '/../vendor/autoload.php';

$code = <<<'CODE'
<?php
    $a = "test";
    $b = "base64_encode";
    $c = array();
    $a();
    array();
    assert($a);
CODE;

class ExtractVars extends NodeVisitorAbstract {
    private $prettyPrinter = null;
    private $variables = [];

    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 );
                var_dump($assignVars);
                // Get string of what assigned to actually is
                $assign = $this->prettyPrinter->prettyPrintExpr($node->var);
                var_dump($assign);
         }
    }

    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() : int  {
        return count(array_unique($this->variables));
    }
}

$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
$stmts = $parser->parse($code);
$traverser = new NodeTraverser;
$varExtract = new ExtractVars();
$traverser->addVisitor($varExtract);
$ast = $traverser->traverse($stmts);
print_r($varExtract->getVariables());

我定义了一个数组“$variables”来存储 LeaveNode 遇到的变量名。


现在我不能使用单个 PHP 文件。这个Visitor.php不会保留最后几行初始化代码,我需要在主文件中初始化并获取数组中的值。像这样

//main.php
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
$stmts = $parser->parse($code);
$traverser = new NodeTraverser;
$traverser->addVisitor($VisitorClassName);
$ast = $traverser->traverse($stmts);

//XXvisitor.php
<?php
use PhpParser\Node;
use PhpParser\NodeVisitorAbstract;

class Visitor extends NodeVisitorAbstract
{
    public function leaveNode(Node $node)
    {
      
    }
}

我只写了一个php文件,没有进行项目开发。如何从主文件中获取存储在数组中的变量名?我目前正在使用 afterTraverse 函数来输出我的数组,但我认为这不正确

public function afterTraverse(array $nodes) {
        var_dump($this->variables);
    }

我是否需要在主文件中初始化我的类并使用 $obj->array 来访问它

4

0 回答 0