如何使用nikic / PHP-Parser解析和列出所有类方法

时间:2016-08-03 15:38:40

标签: php lexer

阅读文档我可以转储收集的信息,但是没有迭代集合以按特定节点类型过滤的示例。

use PhpParser\ParserFactory;
use PhpParser\Error;
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
try {
    $statements = $parser->parse(file_get_contents("SomeClass.php"));
    $methods = array_filter($statements, function($statement) {
        // some form of filtering for methods
    });
} catch (Error $exception) {
    echo "parse error ~> ", $exception->getMessage();
}

1 个答案:

答案 0 :(得分:1)

选项1-简单的节点查找

use PhpParser\{Node, NodeFinder, ParserFactory};

/** Parse file. */
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
$stmts  = $parser->parse(file_get_contents("SomeClass.php"));

/** Traverse. */
$nodeFinder = new NodeFinder();
$methods = $nodeFinder->findInstanceOf($stmts, Node\Stmt\ClassMethod::class);

/** Dump. */
var_dump($methods);

选项2-完整的“节点访问者”机制

use PhpParser\{Node, NodeTraverser, NodeVisitorAbstract, ParserFactory};

/** Filter definition. */
$methods   = [];
$traverser = new NodeTraverser();
$traverser->addVisitor(new class extends NodeVisitorAbstract {
    function enterNode(Node $node) {
        if ($node instanceof Node\Stmt\ClassMethod) {
            global $methods;
            $methods[] = $node;
            return NodeTraverser::DONT_TRAVERSE_CHILDREN;
        }
    }
});

/** Parse file. */
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
$stmts  = $parser->parse(file_get_contents("SomeClass.php"));

/** Traverse using our filter. */
$traverser->traverse($stmts);

/** Dump. */
var_dump( $methods );