给定一个类实例,是否可以确定它是否实现了特定的接口?据我所知,没有内置函数可以直接执行此操作.我有什么选择(如果有的话)?
interface IInterface { } class TheClass implements IInterface { } $cls = new TheClass(); if ($cls instanceof IInterface) { echo "yes"; }
您可以使用"instanceof"运算符.要使用它,左操作数是一个类实例,右操作数是一个接口.如果对象实现特定接口,则返回true.
正如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);
}
这些测试基于这个简单的代码.
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
只是为了帮助将来搜索is_subclass_of也是一个很好的变种(对于PHP 5.3.7+):
if (is_subclass_of($my_class_instance, 'ISomeInterfaceName')){ echo 'I can do it!'; }
您还可以执行以下操作
public function yourMethod(YourInterface $objectSupposedToBeImplementing) { //..... }
如果$objectSupposedToBeImplementing
没有实现YourInterface
接口,它将抛出可恢复的错误.