5

トークナイザーを使用してファイルをスキャンし、定義されたすべてのクラス、それらが拡張するもの、作成されたインスタンス、および静的に呼び出されたものを見つけようとしています。

<?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()???
        }
    }
}

このコードを拡張して、上記のようなPHPクラスの追加のインスタンスを見つけるにはどうすればよいですか?

4

4 に答える 4

2

PHPコードを解析してから解釈することは、正規表現を使用してうまく解決できるものではありません。ステートマシンのように、スコープ、クラス名、継承などを実際に理解して、必要なことを実行できる、もっと賢いものが必要になります。

たまたま、ステートマシンに基づいてPHPからJavascriptへのコンバーターを作成しました。これは、あなたがやりたいことのほとんどをほぼ実行します。

定義されたすべてのクラス

はい、すべてのクラスがすべての変数がリストされたClassScopeを作成し、それらのメソッドがFunctionScopeとして作成されるため、クラスにどのメソッドがあるかがわかります。

彼らが拡張するものは何でも

はい、すべてのクラスには、ClassScope->$parentClassesにリストされている親クラスがあります

作成されたインスタンス

いいえ。ただし、これらを記録するためのコードを追加するのは難しくありません。

それらが静的に呼び出されたときはいつでも。

いいえ-しかし、それは実際には正規表現で行うことができます。

それはあなたの問題を正確に解決するわけではありませんが、現状のプロジェクトはあなたがやりたいことへの道の95%をあなたにもたらし、それは数週間の仕事を節約するでしょう。

于 2013-02-20T13:41:57.957 に答える
0

Incluedはおそらくここで調べる価値がありますが、それを超えるファイル/クラスが含まれているデータとその回数が提供されるとは思いません。

于 2013-02-13T15:42:40.730 に答える
0

トークンを分析するだけではこれができないと思います。

クラス名については、継承関係を含め、それが表す実際の定義と、インターフェイスを実装するためにコードで使用されているかどうかを知る必要があります。クラス/インターフェース定義は別のファイルにある可能性があります。そのファイルは、ある条件下で含まれる可能性があります。同じクラス名が異なるファイルで異なる方法で定義されている場合があります。したがって、一般に、システムを構成するすべてのファイルを一度に処理する必要があります。

基盤として必要なのは、PHPを解析し、実際のシンボルテーブルを構築するツールです。あなたはそれからあなたの結果を計算することができるかもしれません。(このようなツールは、開始点としてトークンを分析しますが、簡単なトークンスキャンよりもはるかに多くの作業が必要です)。

于 2013-02-15T22:09:14.173 に答える
0

コードをロードするだけで、組み込みのReflection API(ReflectionClass :: _ Construct()など)を使用して各クラスを調べることができるようです。

クラス自体を取得するには、組み込みのget_declared_classes()を使用します。

(注:私はこれを試したことがないので、YMMVです。)

于 2013-02-19T23:07:02.153 に答える