2

在进行静态分析时是否可以通过标准 PHP 标记器获取对象类型?

我正在尝试评估实现设计模式检测器的可能性,但为了实现我的目标,我必须在向它们发送消息时(即在它们上调用方法时)知道对象的实际类型。

在此先感谢大家会尽力帮助我。

4

2 回答 2

2

是的……但这并不容易。我的代码示例(使用状态)为此。

$file_path = 'template.php';

$contents = file_get_contents($file_path);
$tokens = token_get_all($contents);

$classes = array();
$namespace_state = false;           // we are not inside namespace name
$class_or_interface_state = false;  // we are not inside class name

$current_namespace = '';
foreach ($tokens as $token)
    {
    switch (true)
        {
        // namespace?
        case (is_array($token) && $token[0] == T_NAMESPACE): 
            $namespace_state = true; // we are going inside namespace name
            break;

        // semicolon inside namespace name?
        case ($token === ';' && $namespace_state): 
            $namespace_state = false; // we are leaving namespace name
            $current_namespace .= '\\'; // add it to namespace name
            break;

        // \(namespace separator) inside namespace name?
        case (is_array($token) && $namespace_state && $token[0] == T_NS_SEPARATOR):
            $current_namespace .= '\\'; // add it to namespace name
            break;

        // string inside namespace name?
        case (is_array($token) && $namespace_state && $token[0] == T_STRING):
            $current_namespace .= $token[1]; // add it to namespace name
            break;

        // class or interface?
        case (is_array($token) && ($token[0] == T_CLASS || $token[0] == T_INTERFACE)):
            $class_or_interface_state = true; // we are going inside class or interface name
            break;

        // string inside class or interface name?
        case (is_array($token) && $token[0] == T_STRING && $class_or_interface_state):
            $class_or_interface_state = false; // we are leaving class or interface name
            $classes[strtolower($current_namespace . $token[1])] = $file_path; // we have founded full class name
            break;
        }
    }

var_dump($classes);

PS 此代码未在一个文件中使用少量命名空间进行测试。

于 2013-07-04T08:23:49.347 回答
0

抱歉:(。在尝试编写一个完整的示例时,我意识到似乎可以通过查看对象实例化(即“新”调用)和跟踪变量分配来推断变量类型。但是我需要实现一个适当的算法来解析 token_get_all() 的结果。@sectus 让我再次感谢您的时间和耐心。

于 2013-07-05T09:57:30.707 回答