【发布时间】:2013-07-04 08:08:42
【问题描述】:
在进行静态分析时是否可以通过标准的 PHP 分词器获取对象类型?
我正在尝试评估实现设计模式检测器的可能性,但为了实现我的目标,我必须知道向对象发送消息时(即在对象上调用方法时)的实际类型。
提前感谢大家会尽力帮助我。
【问题讨论】:
在进行静态分析时是否可以通过标准的 PHP 分词器获取对象类型?
我正在尝试评估实现设计模式检测器的可能性,但为了实现我的目标,我必须知道向对象发送消息时(即在对象上调用方法时)的实际类型。
提前感谢大家会尽力帮助我。
【问题讨论】:
是的……但这并不容易。我的代码示例(使用状态)。
$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);
附:此代码未在一个文件中使用少量命名空间进行测试。
【讨论】:
对不起:(。在尝试编写一个完整的示例时,我意识到似乎可以通过查看对象实例化(即“新”调用)和跟踪变量分配来推断变量类型。但是我需要实现一个正确的算法来解析 token_get_all() 的结果。 @sectus 让我再次感谢您的时间和耐心。
【讨论】: