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
最后一个测试显示以下错误:
可捕获的致命错误:第 XX 行的 C:\Users\abcdefghijklmn\debug.php 中不允许实例化“Closure”
我尝试过的事情:
- 使用
$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;
}
}
I need to check whether a certain class extends or implements a particular interface.
Note that the class name is a variable string, ie, there won't be any instance of this class.
Users are supposed to select a class from a list of classes and the system is supposed to check whether the class implements a certain interface or not. The list of classes is variable (according to the PHP software currently running), some of these classes can be initialized and others cannot.
Here's the code I'm using:
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
That last test shows up the following error:
Catchable fatal error: Instantiation of 'Closure' is not allowed in C:\Users\abcdefghijklmn\debug.php on line XX
Things I tried:
- Using
$obj=new @$obj();
:- error is hidden but it still faults/dies. - Using
try{}catch(){}
around offending block :- nothing different happens - Using
'class' instanceof 'class'
(where $obj is a string) :- returnsfalse
unconditionally
Please note that the mandatory class initialization used in this method...sucks. Creating instances means unnecessary memory consumption, loss in speed and more prone to errors (imagine some weirdo class that when instantiated without parameters it proceeds to destroy your HDD ;) ).
So, if there's any other way, I'd simply love to know about it.
Edit: This is (hopefully) the final code:-
/**
* 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;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试使用 PHP 的 ReflectionClass 代替,例如
Try using PHP's ReflectionClass instead, e.g.
使用ReflectionClass:
Use the ReflectionClass: