【问题标题】:PHP get_token_all objects typePHP get_token_all 对象类型
【发布时间】:2013-07-04 08:08:42
【问题描述】:

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

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

提前感谢大家会尽力帮助我。

【问题讨论】:

    标签: php object types static


    【解决方案1】:

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

    $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);
    

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

    【讨论】:

    • 如果您添加解释,这将是一个更好的答案:)
    • 是的,通常更努力 = moar +1
    • 对不起,但乍一看,我看不到在哪里实现了对对象调用方法的检测。例如:$object->method($parameter1, $parameter2).
    • @gr4devel,它是类和接口的检测。将示例代码添加到您的问题中。
    • 非常感谢您的耐心等待。实际上我想做的是通过静态分析 PHP 代码来推断变量的类型。因此,如果我有上面提到的调用 $object->method($parameter1, $parameter2) 我想知道 $object、$parameter1 和 $parameter2 的类型。我需要这些信息的原因是我要实现的设计模式检测规则与讨论的实体类型密切相关。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2017-11-21
      • 2013-07-18
      • 2017-09-09
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 2013-10-14
      • 2015-02-17
      相关资源
      最近更新 更多