Answers:
从这里指出,您可以使用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
一些简单的性能测试显示了每种方法的成本:
循环外的对象构造(100,000次迭代) ____________________________________________ | class_implements | 反思| instanceOf | | ------------------ | ---------------- | ------------ | | 140毫秒| 290毫秒| 35毫秒| '--------------------------------------------' 循环内的对象构造(100,000次迭代) ____________________________________________ | class_implements | 反思| instanceOf | | ------------------ | ---------------- | ------------ | | 182毫秒| 340毫秒| 83毫秒| 廉价的构造函数 | 431毫秒| 607毫秒| 338毫秒| 昂贵的构造函数 '--------------------------------------------'
100,000次迭代 ____________________________________________ | class_implements | 反思| instanceOf | | ------------------ | ---------------- | ------------ | | 149毫秒| 295毫秒| 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";
}
instanceof
再次使用。
class_implements()
因为它显然可以更快地调用class_implements然后再调用in_array,而不是进行完整的反映
只是为了帮助将来进行搜索,is_subclass_of还是一个不错的变体(对于PHP 5.3.7+):
if (is_subclass_of($my_class_instance, 'ISomeInterfaceName')){
echo 'I can do it!';
}
该is_a
功能在这里缺失,作为替代。
我进行了一些性能测试,以检查哪种陈述的方法是最有效的。
instanceof [object] took 7.67 ms | + 0% | ..........
is_a [object] took 12.30 ms | + 60% | ................
is_a [class] took 17.43 ms | +127% | ......................
class_implements [object] took 28.37 ms | +270% | ....................................
reflection [class] took 34.17 ms | +346% | ............................................
添加了一些点以实际“感觉到”差异。
由此产生:https : //3v4l.org/8Cog7
如果您有检查对象,请使用instance of
已接受答案中所述的方法。
如果您要检查某个班级,请使用is_a
。
考虑到您想基于您需要的接口实例化一个类的情况,使用起来更加出色is_a
。只有一个例外-构造函数为空时。
例:
is_a(<className>, <interfaceName>, true);
它将返回bool
。第三个参数“ allow_string ”允许它在不实例化类的情况下检查类名称。