PHP 字符串和不可初始化类的 instanceof

发布于 2024-10-06 05:31:08 字数 1804 浏览 0 评论 0原文

我需要检查某个类是否扩展或实现了特定的接口。

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

用户应该从类列表中选择一个类,系统应该检查该类是否实现了某个接口。类列表是可变的(根据当前运行的 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) :- returns false 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏夜暖风 2024-10-13 05:31:08

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

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

Try using PHP's ReflectionClass instead, e.g.

$rc = new ReflectionClass($obj);
return $rc->implementsInterface($cls);
或十年 2024-10-13 05:31:08

使用ReflectionClass:

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

Use the ReflectionClass:

function is_instance_of($obj,$cls){
    $ref=new ReflectionClass($obj);
    return in_array($cls, array_keys($ref->getInterfaces());
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文