2016-06-13 8 views
0

На существующем проекте я работаю, мы имеем следующую ситуацию:PHP Проверьте фактический класс реализует интерфейс

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, а не только родительский класс? Проверка должна вернуть true за $ B и $ D и false за $ C. Обычно вы делали бы

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

но в нашей ситуации это вернет истину, которой не следует.

Подход может состоять в том, чтобы проанализировать файл и проверить, действительно ли класс реализует A с помощью функции token_get_all. Но прежде чем это сделать, я хочу спросить, есть ли более элегантные решения.

Я знаю, это звучит странно, но ситуация такая, какая есть, и иерархия классов не может быть изменена. Любые идеи были бы полезны.

+0

Если B реализует A, не будет ли все классы расширения B автоматически реализовывать A тоже? – Guiroux

+0

Да, но мне нужны только классы, на самом деле имеющие инструкцию A. Иерархия указана, потому что это старая унаследованная система. – Laoneo

+0

', но мне нужны только классы, на самом деле есть инструменты. Вы можете объяснить это, не углубляясь в объяснение? – Guiroux

ответ

0

Эта функция возвращает true, только если интерфейс A реализован не расширен через родительский класс.

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

Но он также возвращает false для D. – Laoneo

Смежные вопросы