如何找到PHP文件中使用的所有类?

Xeo*_*oss 5 php code-analysis class tokenize

我正在尝试使用标记生成器扫描文件以查找所有已定义的类,它们扩展的任何内容,任何创建的实例以及它们被静态调用的任何时间.

<?php

$tokens = token_get_all(file_get_contents($file));

$used_classes = array();
$defined_classes = array();
$variable_classes = array();

foreach($tokens as $i => $token) {

    if(is_array($token)) {

        if(isset($tokens[$i - 2][0], $tokens[$i - 1][0])) {

            // new [class]
            if ($tokens[$i - 2][0] == T_NEW AND $tokens[$i - 1][0] == T_WHITESPACE) {

                if($tokens[$i][0] == T_STRING) {
                    $used_classes[$token[1]] = TRUE;

                // new $variable()
                } elseif($tokens[$i][0] == T_VARIABLE) {    

                    // @todo, this is really broken. However, do best to look for the assignment
                    if(preg_match('~\$var\s*=\s*([\'"])((?:(?!\1).)*)\1~', $text, $match)) {
                        if(empty($extension_classes[$match[2]])) {
                            $used_classes[$match[2]] = TRUE;
                        }
                    } elseif($token[1] !== '$this') {
                        $variable_classes[$token[1]] = TRUE;
                    }
                }

            }

            // class [class]
            if ($tokens[$i - 2][0] == T_CLASS AND $tokens[$i - 1][0] == T_WHITESPACE) {

                if($tokens[$i][0] == T_STRING) {
                    $defined_classes[$token[1]] = TRUE;
                }
            }


            // @todo: find more classes \/

            // class [classname] extends [class] ???
            // [class]::method()???
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如何扩展此代码以查找上面提到的任何其他PHP类实例?

Dan*_*ack 2

解析然后解释 PHP 代码并不是使用正则表达式可以很好解决的问题。您需要一个更聪明的东西,例如状态机,它实际上可以理解范围、类名、继承等内容,以便能够执行您想要的操作。

碰巧的是,我碰巧编写了一个基于状态机的 PHP 到 Javascript转换器,它几乎可以完成您想做的大部分事情:

所有定义的类

是的,所有类都会创建一个 ClassScope,其中列出了它们的所有变量,并且它们的方法被创建为 FunctionScope,因此您可以知道一个类有哪些方法。

他们扩展的任何东西

是的,每个类都有其父类在 ClassScope->$parentClasses 中列出

任何创建的实例

不,但是添加额外的代码来记录这些并不难。

任何时候它们被静态调用。

不,但这实际上可以通过正则表达式来完成。

尽管它并不能完全解决您的问题,但该项目目前可以让您完成 95% 的目标,这将节省几周的工作时间。