Учитывая экземпляр класса, можно ли определить, реализует ли он конкретный интерфейс? Насколько я знаю, для этого не существует встроенной функции. Какие у меня варианты (если есть)?
interface IInterface { } class TheClass implements IInterface { } $cls = new TheClass(); if ($cls instanceof IInterface) { echo "yes"; }
Вы можете использовать оператор «instanceof». Чтобы использовать его, левый операнд является экземпляром класса, а правый операнд – интерфейсом. Он возвращает true, если объект реализует определенный интерфейс.
Как class_implements()
, вы можете использовать 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 ms | Дешевый конструктор | 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
.
Вы также можете использовать API отражения в PHP, чтобы более точно протестировать это:
$class = new ReflectionClass('TheClass'); if ($class->implementsInterface('IInterface')) { print "Yep!\n"; }
Просто, чтобы помочь будущим поисковым запросам, is_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
.