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

给定一个类实例,是否有可能确定它是否实现了一个特定的接口? 据我所知,没有一个内置的函数直接做到这一点。 我有什么select(如果有的话)?

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

你可以使用“instanceof”操作符。 要使用它,左操作数是一个类实例,右操作数是一个接口。 如果对象实现特定的接口,则返回true。

从那里指出,你可以使用class_implements() 。 与Reflection一样,这允许您将类名称指定为string,并且不需要该类的实例:

 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

性能testing

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

给定一个对象的实例

循环外的对象构造(100,000次迭代)
  ____________________________________________
 |  class_implements | 反思|  instanceOf |
 | ------------------ | ------------ | ------------ |
 |  140 ms |  290 ms |  35 ms |
 '--------------------------------------------'

循环内的对象构造(100,000次迭代)
  ____________________________________________
 |  class_implements | 反思|  instanceOf |
 | ------------------ | ------------ | ------------ |
 |  182 ms |  340 ms |  83毫秒| 便宜的构造函数
 |  431 ms |  607 ms |  338 ms | 昂贵的构造函数
 '--------------------------------------------'

只给出一个类名

 100,000次迭代
  ____________________________________________
 |  class_implements | 反思|  instanceOf |
 | ------------------ | ------------ | ------------ |
 |  149 ms |  295 ms |  N / A |
 '--------------------------------------------'

昂贵的__construct()是:

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

这些testing是基于这个简单的代码 。

nlaq指出, instanceof可用于testing对象是否是实现接口的类的实例。

但是instanceof不区分类的types和接口。 你不知道对象是不是恰好被称为IInterface

您也可以在PHP中使用reflectionAPI来更具体地testing:

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

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

只是为了帮助未来的searchis_subclass_of也是一个很好的变种(对于PHP 5.3.7 +):

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

您也可以执行以下操作

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

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

Interesting Posts