PHP检查实际的类是否正在实现接口

时间:2016-06-13 09:03:44

标签: php class inheritance interface

在我正在处理的现有项目中,我们遇到以下情况:

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();

确定实际类是否实现接口 A 而不仅仅是父类的正确方法是什么?对于$ B,检查应返回 true ,对于$ C,检查应返回 false 。通常你会这样做

if( $C instanceof A ) { //do the work }

但在我们的情况下,这将返回true,不应该。

一种方法可以是解析文件并测试该类是否真的使用token_get_all函数实现了A.但在此之前,我想问一下是否有更优雅的解决方案。

我知道这听起来很奇怪,但情况就是如此,并且无法更改类层次结构。任何见解都会有所帮助。

2 个答案:

答案 0 :(得分:0)

仅当接口A未通过父类扩展时,此函数才返回true。

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;
}

答案 1 :(得分:0)

找到此解决方案:

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;
}