To know which interfaces a class implements, just use the function SPL 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 means, but you need to make sure that the instance is an interface, otherwise you can create an inconsistency by returning extended class instead of interfaces.
Moreover, with instanceof
it is assumed that you already know the name 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’s good to make it clear that I don’t mean it’s wrong to use instanceof
for such purpose (within the context of the question), provided that the exceptions are observed.
However, it is good to highlight the inconsistency when indicating the use of instanceof
for this purpose. For security, use the most consistent, the function class_implements()
.
Reflection?
I would rather not even comment use of Reflection
because, for static tasks, it makes no sense to use OOP classes.
But if you already have an instance of Reflectionclass(), can take advantage of it to get a list of 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: http://php.net/manual/en/reflectionclass.getinterfaces.php
Note: In the examples above show only how to abstract the data. No need to show how to use if else
, in_array()
and things like, to take the name of an object that might be present in the result. After all, whoever is reading this must already know how to use such basic things.
Right, that’s right +1. Now I wonder if
instanceof
was a correct approach of PHP to detect interfaces– Wallace Maxters