Проверка того, реализует ли класс экземпляра интерфейс?

Учитывая экземпляр класса, можно ли определить, реализует ли он конкретный интерфейс? Насколько я знаю, для этого не существует встроенной функции. Какие у меня варианты (если есть)?

Related of "Проверка того, реализует ли класс экземпляра интерфейс?"

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"; } 

См. 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 something !'; } 

Вы также можете сделать следующее

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

Он выдаст восстановимую ошибку, если $objectSupposedToBeImplementing не реализует интерфейс YourInterface .