Given a class instance, is it possible to determine if it implements a particular interface? As far as I know, there isn\'t a built-in function to do this directly. What opt
The is_a
function is missing here as alternative.
I did some performance tests to check which of the stated ways is the most performant.
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% | ............................................
Added some dots to actually "feel" see the difference.
Generated by this: https://3v4l.org/8Cog7
In case you have an object to check, use instance of
like mentioned in the accepted answer.
In case you have a class to check, use is_a
.
Given the case you want to instantiate a class based on an interface you require it to have, it is more preformant to use is_a
. There is only one exception - when the constructor is empty.
Example:
is_a(<className>, <interfaceName>, true);
It will return bool
. The third parameter "allow_string" allows it to check class names without instantiating the class.
nlaq points out that instanceof
can be used to test if the object is an instance of a class that implements an interface.
But instanceof
doesn't distinguish between a class type and an interface. You don't know if the object is a class that happens to be called IInterface
.
You can also use the reflection API in PHP to test this more specifically:
$class = new ReflectionClass('TheClass');
if ($class->implementsInterface('IInterface'))
{
print "Yep!\n";
}
See http://php.net/manual/en/book.reflection.php
Just to help future searches is_subclass_of is also a good variant (for PHP 5.3.7+):
if (is_subclass_of($my_class_instance, 'ISomeInterfaceName')){
echo 'I can do it!';
}
You can also do the following
public function yourMethod(YourInterface $objectSupposedToBeImplementing) {
//.....
}
It will throw an recoverable error if the $objectSupposedToBeImplementing
does not implement YourInterface
Interface.
interface IInterface
{
}
class TheClass implements IInterface
{
}
$cls = new TheClass();
if ($cls instanceof IInterface) {
echo "yes";
}
You can use the "instanceof" operator. To use it, the left operand is a class instance and the right operand is an interface. It returns true if the object implements a particular interface.
As therefromhere points out, you can use class_implements()
. Just as with Reflection, this allows you to specify the class name as a string and doesn't require an instance of the class:
interface IInterface
{
}
class TheClass implements IInterface
{
}
$interfaces = class_implements('TheClass');
if (isset($interfaces['IInterface'])) {
echo "Yes!";
}
class_implements()
is part of the SPL extension.
See: http://php.net/manual/en/function.class-implements.php
Some simple performance tests show the costs of each approach:
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 | '--------------------------------------------'
Where the expensive __construct() is:
public function __construct() {
$tmp = array(
'foo' => 'bar',
'this' => 'that'
);
$in = in_array('those', $tmp);
}
These tests are based on this simple code.