Учитывая экземпляр класса, можно ли определить, реализует ли он конкретный интерфейс? Насколько я знаю, для этого не существует встроенной функции. Какие параметры у меня есть (если есть)?
Проверка того, реализует ли класс экземпляра интерфейс?
Ответ 1
interface IInterface
{
}
class TheClass implements IInterface
{
}
$cls = new TheClass();
if ($cls instanceof IInterface) {
echo "yes";
}
Вы можете использовать оператор "instanceof". Чтобы использовать его, левый операнд является экземпляром класса, а правый операнд - интерфейсом. Он возвращает true, если объект реализует определенный интерфейс.
Ответ 2
Как указывает therefromhere, вы можете использовать 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
Тесты производительности
Некоторые простые тесты производительности показывают затраты на каждый подход:
Учитывая экземпляр объекта
Object construction outside the loop (100,000 iterations) ____________________________________________ | class_implements | Reflection | instanceOf | |------------------|------------|------------| | 140 ms | 290 ms | 35 ms | '--------------------------------------------' Object construction inside the loop (100,000 iterations) ____________________________________________ | class_implements | Reflection | instanceOf | |------------------|------------|------------| | 182 ms | 340 ms | 83 ms | Cheap Constructor | 431 ms | 607 ms | 338 ms | Expensive Constructor '--------------------------------------------'
Указано только имя класса
100,000 iterations ____________________________________________ | class_implements | Reflection | instanceOf | |------------------|------------|------------| | 149 ms | 295 ms | N/A | '--------------------------------------------'
Если дорогой __construct():
public function __construct() {
$tmp = array(
'foo' => 'bar',
'this' => 'that'
);
$in = in_array('those', $tmp);
}
Эти тесты основаны на этом простом коде.
Ответ 3
nlaq указывает, что instanceof
может использоваться для проверки, является ли объект экземпляром класса, реализующего интерфейс.
Но instanceof
не различает тип класса и интерфейс. Вы не знаете, является ли объект классом, который называется IInterface
.
Вы также можете использовать API-интерфейс отражения в PHP, чтобы проверить это более конкретно:
$class = new ReflectionClass('TheClass');
if ($class->implementsInterface('IInterface'))
{
print "Yep!\n";
}
Ответ 4
Просто для поиска будущих поисков is_subclass_of также является хорошим вариантом (для PHP 5.3.7 +):
if (is_subclass_of($my_class_instance, 'ISomeInterfaceName')){
echo 'I can do something !';
}
Ответ 5
Вы также можете сделать следующее
public function yourMethod(YourInterface $objectSupposedToBeImplementing) {
//.....
}
Он выдает возвращаемую ошибку, если $objectSupposedToBeImplementing
не реализует интерфейс YourInterface
.