我需要来检查某个类是否扩展或实现了特定的接口。通过字符串和非可初始化类的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;
}
}
作为一个方面说明,这行不会导致PHP版本<5的解析错误? `if(PHP_MAJOR_VERSION> 4)返回$ obj instanceof $ cls;`条件会阻止*执行*在PHP 4或更少,但解析器仍然需要解析它......我不认为它会很对此感到高兴。 – cdhowie 2010-12-06 10:55:57
好点。对此我不确定。任何想法来解决它?我可以使用好ol'eval;):D – Christian 2010-12-06 10:58:02