On an existing project I'm working on, we have the following situation:
interface A { }
class B implements A { }
class C extends B { }
class D extends B implements A { }
$B = new B();
$C = new C();
$D = new D();
What is the proper way to figure out if the actual class implements the interface A and not only the parent class? The check should return true for $B and $D and false for $C. Normally you would do
if( $C instanceof A ) { //do the work }
but in our situation this will return true which shouldn't.
An approach can be to parse the file and test if the class really implements A with the token_get_all function. But before doing that, I want to ask if there are more elegant solutions.
I know it sounds weird, but the situation is as it is and the class hierarchy can't be changed. Any insights would be helpful.
This function returns true only if interface A is implemented not extended via parent class.
echo checkimplements($B, "A"); //Returns True
function checkimplements($class, $interfacename)
{
$ownInterfaces = class_implements($class);
$parent = get_parent_class($class);
if($parent) {
$parentInterfaces = class_implements($parent);
} else {
$parentInterfaces = array();
}
$diff = array_diff($ownInterfaces, $parentInterfaces);
$found = in_array($interfacename, $diff);
return $found;
}
found this solution:
function implementsInterface($class, string $interface) : bool
{
$result = $class instanceof $interface;
if ($result) {
return true;
}
foreach (class_parents($class) as $subClass) {
if ($result) {
break;
}
$result = implementsInterface($subClass, $interface);
}
return $result;
}