Respostas:
interface IInterface
{
}
class TheClass implements IInterface
{
}
$cls = new TheClass();
if ($cls instanceof IInterface) {
echo "yes";
}
Você pode usar o operador "instanceof". Para usá-lo, o operando esquerdo é uma instância de classe e o operando direito é uma interface. Retorna true se o objeto implementa uma interface específica.
Como a partir daí , você pode usar class_implements()
. Assim como no Reflection, isso permite que você especifique o nome da classe como uma string e não requer uma instância da classe:
interface IInterface
{
}
class TheClass implements IInterface
{
}
$interfaces = class_implements('TheClass');
if (isset($interfaces['IInterface'])) {
echo "Yes!";
}
class_implements()
faz parte da extensão SPL.
Veja: http://php.net/manual/en/function.class-implements.php
Alguns testes simples de desempenho mostram os custos de cada abordagem:
Construção de objetos fora do loop (100.000 iterações) ____________________________________________ | class_implements | Reflexão instanceOf | | ------------------ | ------------ | ------------ | | 140 ms | 290 ms | 35 ms | '--------------------------------------------' Construção de objetos dentro do loop (100.000 iterações) ____________________________________________ | class_implements | Reflexão instanceOf | | ------------------ | ------------ | ------------ | | 182 ms | 340 ms | 83 ms | Construtor Barato | 431 ms | 607 ms | 338 ms | Construtor caro '--------------------------------------------'
100.000 iterações ____________________________________________ | class_implements | Reflexão instanceOf | | ------------------ | ------------ | ------------ | | 149 ms | 295 ms | N / a '--------------------------------------------'
Onde o __construct () caro é:
public function __construct() {
$tmp = array(
'foo' => 'bar',
'this' => 'that'
);
$in = in_array('those', $tmp);
}
Esses testes são baseados neste código simples .
O nlaq aponta que instanceof
pode ser usado para testar se o objeto é uma instância de uma classe que implementa uma interface.
Mas instanceof
não faz distinção entre um tipo de classe e uma interface. Você não sabe se o objeto é uma classe que é chamada IInterface
.
Você também pode usar a API de reflexão no PHP para testar isso mais especificamente:
$class = new ReflectionClass('TheClass');
if ($class->implementsInterface('IInterface'))
{
print "Yep!\n";
}
class_implements()
instanceof
novamente.
class_implements()
desde a sua obviamente mais rápido para chamar class_implements e depois in_array, em vez de fazer uma reflexão completa
Apenas para ajudar futuras pesquisas, o is_subclass_of também é uma boa variante (para PHP 5.3.7+):
if (is_subclass_of($my_class_instance, 'ISomeInterfaceName')){
echo 'I can do it!';
}
A is_a
função está faltando aqui como alternativa.
Fiz alguns testes de desempenho para verificar qual das maneiras declaradas é a mais eficiente.
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% | ............................................
Foram adicionados alguns pontos para realmente "sentir" ver a diferença.
Gerado por isso: https://3v4l.org/8Cog7
Caso você tenha um objeto para verificar, use instance of
como mencionado na resposta aceita.
Caso você tenha uma turma para verificar, use is_a
.
Dado o caso em que você deseja instanciar uma classe com base em uma interface que você precisa, é mais recomendável usar is_a
. Há apenas uma exceção - quando o construtor está vazio.
Exemplo:
is_a(<className>, <interfaceName>, true);
Voltará bool
. O terceiro parâmetro " allow_string " permite verificar os nomes das classes sem instanciar a classe.