当前位置:  开发笔记 > 编程语言 > 正文

检查实例的类是否实现了接口?

如何解决《检查实例的类是否实现了接口?》经验,为你挑选了5个好方法。

给定一个类实例,是否可以确定它是否实现了特定的接口?据我所知,没有内置函数可以直接执行此操作.我有什么选择(如果有的话)?



1> 小智..:
interface IInterface
{
}

class TheClass implements IInterface
{
}

$cls = new TheClass();
if ($cls instanceof IInterface) {
    echo "yes";
}

您可以使用"instanceof"运算符.要使用它,左操作数是一个类实例,右操作数是一个接口.如果对象实现特定接口,则返回true.



2> Jess Telford..:

正如wherehere指出的那样,你可以使用class_implements().与Reflection一样,这允许您将类名指定为字符串,并且不需要该类的实例:

interface IInterface
{
}

class TheClass implements IInterface
{
}

$interfaces = class_implements('TheClass');

if (isset($interfaces['IInterface'])) {
    echo "Yes!";
}

class_implements() 是SPL扩展的一部分.

请参阅:http://php.net/manual/en/function.class-implements.php

性能测试

一些简单的性能测试显示了每种方法的成本:

给定一个对象的实例

Object construction outside the loop (100,000 iterations)
 ____________________________________________
| class_implements | Reflection | instanceOf |
|------------------|------------|------------|
| 140 ms           | 290 ms     | 35 ms      |
'--------------------------------------------'

Object construction inside the loop (100,000 iterations)
 ____________________________________________
| class_implements | Reflection | instanceOf |
|------------------|------------|------------|
| 182 ms           | 340 ms     | 83 ms      | Cheap Constructor
| 431 ms           | 607 ms     | 338 ms     | Expensive Constructor
'--------------------------------------------'

只给出一个类名

100,000 iterations
 ____________________________________________
| class_implements | Reflection | instanceOf |
|------------------|------------|------------|
| 149 ms           | 295 ms     | N/A        |
'--------------------------------------------'

昂贵的__construct()在哪里:

public function __construct() {
    $tmp = array(
        'foo' => 'bar',
        'this' => 'that'
    );  

    $in = in_array('those', $tmp);
}

这些测试基于这个简单的代码.


感谢您的性能测试.很有帮助.

3> Bill Karwin..:

nlaq指出,instanceof可以用来测试对象是否是实现接口的类的实例.

instanceof不区分类类型和接口.你不知道,如果对象是一个恰好是叫IInterface.

您还可以使用PHP中的反射API来更具体地测试它:

$class = new ReflectionClass('TheClass');
if ($class->implementsInterface('IInterface'))
{
  print "Yep!\n";
}

见http://php.net/manual/en/book.reflection.php


另见[`class_implements()`](http://php.net/manual/en/function.class-implements.php)
这可以用于"静态"类
如果使用名称空间,那么接口和具有相同名称的类之间不会存在歧义,您可以再次安全地使用`instanceof`.

4> d.raev..:

只是为了帮助将来搜索is_subclass_of也是一个很好的变种(对于PHP 5.3.7+):

if (is_subclass_of($my_class_instance, 'ISomeInterfaceName')){
    echo 'I can do it!';
}



5> Starx..:

您还可以执行以下操作

public function yourMethod(YourInterface $objectSupposedToBeImplementing) {
   //.....
}

如果$objectSupposedToBeImplementing没有实现YourInterface接口,它将抛出可恢复的错误.

推荐阅读
ifx0448363
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有