To know which interfaces a class implements, simply use the SPL function class_implements ()
Scope
array class_implements ( mixed $class [, bool $autoload = true ] )
From PHP 5.1 you can set the class name to string:
$rs = class_implements('Foo');
var_dump($rs);
We can use instanceof as a more practical medium, but we need to make sure that the instance is an interface, otherwise it may create an inconsistency by returning extended classes rather than interfaces.
What's more, with instanceof
it is assumed that you already know the names of the interfaces. With class_implements()
an array of names of the implemented objects is returned. It is most useful for when you do not know which objects are implemented.
These are the objects we will use for testing:
interface iFoo {
}
class Bar {
}
class Foo implements ifoo {
}
class Foo2 extends Bar {
}
Test with 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) {
}
*/
Test with 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.
*/
It is good to make it clear that I do not mean that it is wrong to use instanceof
for this purpose (within the context of the question), provided the caveats are observed.
However, it is good to point out the inconsistency when indicating the use of instanceof
for this purpose. For security, use whichever is more consistent, the class_implements()
function.
Reflection?
I would not even want to comment on the use of Reflection
because for static tasks there is no sense in using OOP classes.
But if you already have an instance of ReflectionClass () , you can take advantage of it to get a list of the interfaces that the object implements:
$rs = new ReflectionClass('Foo');
var_dump($rs->getInterfaces());
/*
array(1) {
["iFoo"]=>
object(ReflectionClass)#2 (1) {
["name"]=>
string(4) "iFoo"
}
}
*/
Reference: link
Note: The examples above show only how to abstract the data. I do not need to show how to use if else
, in_array()
and stuff like that to get the name of an object that might be present in the result. After all, anyone who is reading this should know how to use such basic things.