检查一个实例的类是否实现一个接口?
给定一个类实例,是否有可能确定它是否实现了一个特定的接口? 据我所知,没有一个内置的函数直接做到这一点。 我有什么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"; }
只是为了帮助未来的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
接口,它将会抛出一个可恢复的错误。