Как знать, если класс реализует интерфейс?


В PHP, мы можем реализовать одну (или несколько) interface в классе.

Таким образом:

  interface Authenticable {
       // métodos
  }

  interface Model {
      // métodos
  }

  class Person implements Authenticable, Model {
     // métodos
  }

В приведенном выше примере, Person реализует Authenticable и Model.

Как я могу сделать проверку, чтобы знать, что конкретный класс реализует интерфейс? Например, как определить, что конкретный экземпляр - Person реализует Authenticable?

Примечание: Обычно всегда использовать PHP версии 5.4 >=. Поэтому было бы желательно более текущего возможно, для такой операции.

Author: Wallace Maxters, 2016-10-21

2 answers

Использует оператор instanceof:

interface Authenticable {
     // métodos
}
interface Model {
    // métodos
}
class Person implements Authenticable, Model {
   // métodos
}
$pessoa = new Person();
if ($pessoa instanceof Model) echo "implementa Model";
if ($pessoa instanceof Cloneable) echo "implementa Cloneable";

См работает ideone. И repl.it. Также я GitHub для использования в будущем.

- это Не то, что вы хотите и в тех редких ситуациях, когда это полезно (я думаю, что только если делать что-то вспомогательное средство), но если вы предпочитаете , может быть список все:

interface Authenticable {
     // métodos
}
interface Model {
    // métodos
}
class Person implements Authenticable, Model {
   // métodos
}
$pessoa = new Person();
print_r(class_implements($pessoa));

См работает ideone. И repl.it. Также я GitHub для использования в будущем.

 10
Author: Maniero, 2020-11-11 20:13:04

, Чтобы узнать, какие интерфейсы класс реализует, просто использовать функцию SPL class_implements()

Область

array class_implements ( mixed $class [, bool $autoload = true ] )

Начиная с PHP 5.1 можно задать имя класса как string:

$rs = class_implements('Foo');
var_dump($rs);

Мы Можем использовать instanceof как более практичный, но нужно быть уверенным, что экземпляр-это интерфейс, в противном случае может возникнуть несовместимость, возвращая class расширенным, а не интерфейсы. Причем, instanceof предполагается, что вы уже знаете имя интерфейсов. class_implements() возвращаемый массив имен объектов осуществляется. Это наиболее полезно, когда вы не знаете, какие объекты будут реализованы.

Это те объекты, которые мы используем для тестирования:

interface iFoo {
}

class Bar {
}

class Foo implements ifoo {
}

class Foo2 extends Bar {
}

Тест с class_implements()

$rs = class_implements('Foo');
var_dump($rs);
/*
array(1) {
  ["iFoo"]=>
  string(4) "iFoo"
}
*/

$rs = class_implements('Foo2');
var_dump($rs);
/*
Foo2 é uma instância de Bar, porém, não retorna ao invocar class_implements() por ser uma class e não uma interface. O resultado nesse caso é vazio.

array(0) {
}
*/

Тест с instanceof

O uso do `instanceof` pode causar inconsistência. Veja o exemplo:

$c = new Foo;
if ($c instanceof iFoo) {
    echo 'yes';
} else {
    echo 'no';
}
/*
iFoo é uma interface. O retorno é 'yes'.
*/

$c = new Foo2;
if ($c instanceof Bar) {
    echo 'yes';
} else {
    echo 'no';
}

/*
Bar() não é uma interface, mas ainda assim retorna 'yes' porque instanceof não distingue se o objeto é uma class ou uma interface.
Isso é um exemplo de inconsistência.
*/

Хорошо, чтобы понять, что не хочу говорить будет неправильно использовать instanceof для таких целей (в контексте вопроса), при условии, что при соблюдении предостережений.

Тем не менее, это хорошо, чтобы отметить, на непоследовательность, когда означать использование instanceof для такой цели. В целях безопасности, используйте то, что является более последовательной, функция class_implements().

Reflection?

Я prefereria, ни комментировать использование Reflection потому, что для статических задач, не имеет смысла использовать классы ООП.

, Но если у вас уже есть экземпляр ReflectionClass(), вы можете использовать его, чтобы получить список всех интерфейсов, что объект реализует:

$rs = new ReflectionClass('Foo');
var_dump($rs->getInterfaces());
/*
array(1) {
  ["iFoo"]=>
  object(ReflectionClass)#2 (1) {
    ["name"]=>
    string(4) "iFoo"
  }
}
*/

Артикул: http://php.net/manual/en/reflectionclass.getinterfaces.php

Примечание: В примерах выше, показывают только, как абстрактных данных. Не нужно, чтобы показать, как использовать if else, in_array() и вещи, чтобы получить имя объекта, который может присутствовать в результате. В конце концов, тот, кто читает, это уже должны знать, как использовать вещи как базовые.

 1
Author: Daniel Omine, 2016-10-26 13:17:24