2010-12-06 28 views
3

我需要来检查某个类是否扩展或实现了特定的接口。通过字符串和非可初始化类的PHP instanceof

注意该类名称是一个变量字符串,即不会有这个类的任何实例。

用户应该从类列表中选择一个类,系统应该检查类是否实现了某个接口。类的列表是可变的(根据当前正在运行的PHP软件),其中一些类可以被初始化,而其他类不能。

下面是我使用的代码:

function is_instance_of($obj,$cls){ 
    if(is_string($obj))$obj=new $obj(); 
    if(PHP_MAJOR_VERSION>4)return $obj instanceof $cls; 
    if(PHP_MAJOR_VERSION>3)return is_a($obj,strtolower($cls)); 
    return false; 
} 

var_dump(is_instance_of('MyClass','IMyInterface')); // in theory, true 
var_dump(is_instance_of('Closure','IMyInterface')); // FATAL ERROR 

这最后的测试显示了以下错误:

​​

事情我想:

  • 使用$obj=new @$obj();: - 错误是隐藏的,但它仍然错误/死亡。
  • 周围使用违规块try{}catch(){}: - 没有什么不同情况
  • 使用'class' instanceof 'class'(其中$ obj是一个字符串): - 返回false无条件

请注意,在这种方法中使用的强制性类初始化.. .sucks。创建实例意味着不必要的内存消耗,速度下降以及更容易出错(想象一下当没有参数实例化时它会继续销毁您的硬盘;))。所以,如果还有其他方法,我只想知道它。


编辑:这是(希望)最终代码: -

/** 
* Cross-version instanceof replacement. 
* @param object $obj The instance to check. 
* @param stirng $cls The class/interface name to look for. 
* @return boolean Whether an object extends or implements a particular class 
*  or interface. 
* @link http://stackoverflow.com/questions/4365567/php-instanceof-over-strings-and-non-initializable-classes 
*/ 
function is_instance_of($obj,$cls){ 
    if(is_string($obj) || PHP_MAJOR_VERSION>4){ 
     $rc=new ReflectionClass($obj); 
     return $rc->implementsInterface($cls); 
    }else{ 
     if(PHP_MAJOR_VERSION>3)return is_a($obj,strtolower($cls)); 
     return false; 
    } 
} 
+1

作为一个方面说明,这行不会导致PHP版本<5的解析错误? `if(PHP_MAJOR_VERSION> 4)返回$ obj instanceof $ cls;`条件会阻止*执行*在PHP 4或更少,但解析器仍然需要解析它......我不认为它会很对此感到高兴。 – cdhowie 2010-12-06 10:55:57

+0

好点。对此我不确定。任何想法来解决它?我可以使用好ol'eval;):D – Christian 2010-12-06 10:58:02

回答

2

尝试使用PHP的ReflectionClass代替,例如

$rc = new ReflectionClass($obj); 
return $rc->implementsInterface($cls); 
0

使用ReflectionClass:

function is_instance_of($obj,$cls){ 
    $ref=new ReflectionClass($obj); 
    return in_array($cls, array_keys($ref->getInterfaces()); 
} 
+0

文档建议给构造函数一个字符串;从给出的例子看来,有时可能会给出一个对象。 – 2010-12-06 11:04:15