我需要检查某个类是否扩展或实现了特定接口。
注意类名是一个变量字符串,即不会有这个类的任何实例。
用户应该从类列表中选择一个类,系统应该检查该类是否实现了某个接口。类列表是可变的(根据当前运行的 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
最后一个测试显示以下错误:
可捕获的致命错误:在第 XX 行的 C:\Users\abcdefghijklmn\debug.php 中不允许实例化“闭包”
我尝试过的事情:
- 使用
$obj=new @$obj();
:- 错误被隐藏,但它仍然出现故障/死亡。 - 在违规块周围使用
try{}catch(){}
:-没有什么不同 - 使用
'class' instanceof 'class'
(其中 $obj 是一个字符串):-false
无条件返回
请注意,此方法中使用的强制类初始化......很糟糕。创建实例意味着不必要的内存消耗、速度损失和更容易出错(想象一些奇怪的类,当它在没有参数的情况下实例化时,它会继续破坏你的硬盘;))。所以,如果有任何其他方式,我很想知道它。
编辑:这是(希望)最终代码:-
/**
* 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;
}
}