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