2010-10-22 8 views
21

Ich habe eine SchnittstellePHP: Wie bekomme ich eine Liste von Klassen, die bestimmte Schnittstellen implementieren?

interface IModule { 
    public function Install(); 
} 

und einige Klassen bekam, die diese Schnittstelle

class Module1 implements IModule { 
    public function Install() { 
     return true; 
    } 
} 

class Module2 implements IModule { 
    public function Install() { 
     return true; 
    } 
} 

... 

class ModuleN implements IModule { 
    public function Install() { 
     return true; 
    } 
} 

Wie bekommen eine Liste aller Klassen implementieren, die diese Schnittstelle implementieren? Ich möchte diese Liste mit PHP bekommen.

+2

Sie sollten wahrscheinlich klären, ob Sie die Liste innerhalb von PHP bekommen wollen oder nur wollen Erstellen Sie eine solche Liste für Dokumentationszwecke usw. –

Antwort

20

können Sie PHP verwenden ReflectionClass::implementsInterface und get_declared_classes Funktionen, dies zu erreichen:

$classes = get_declared_classes(); 
$implementsIModule = array(); 
foreach($classes as $klass) { 
    $reflect = new ReflectionClass($klass); 
    if($reflect->implementsInterface('IModule')) 
     $implementsIModule[] = $klass; 
} 
+5

Hinweis: Dies funktioniert nicht, wenn Sie IModule über '__autoload' laden. Aber +1. –

+0

7 Jahre später Kommentar, aber hier ist ein Beispiel dafür, wie Sie Dateien in Autoload von Composer verwenden können, um sicherzustellen, dass bestimmte Dateien jedes Mal geladen werden und mit get_declared_classes verfügbar sind: http://stackoverflow.com/a/18671530/143279 – bleakgadfly

40

Sie nicht Reflection dafür brauchen. Sie können einfach

  • class_implements verwenden - die Schnittstellen zurück, die von der gegebenen Klasse implementiert werden

Nutzungs

in_array('InterfaceName', class_implements('className')); 

Beispiel 1 - Echo aller Klassen der Iterator-Schnittstelle implementiert

foreach (get_declared_classes() as $className) { 
    if (in_array('Iterator', class_implements($className))) { 
     echo $className, PHP_EOL; 
    } 
} 

Beispiel 2 - Return Array aller Klassen die Iterator-Schnittstelle

print_r(
    array_filter(
     get_declared_classes(), 
     function ($className) { 
      return in_array('Iterator', class_implements($className)); 
     } 
    ) 
); 

Das zweite Beispiel erfordert PHP5.3 aufgrund des Rückrufs Implementierung eine anonyme Funktion zu sein.

11

Allgemeine Lösung:

function getImplementingClasses($interfaceName) { 
    return array_filter(
     get_declared_classes(), 
     function($className) use ($interfaceName) { 
      return in_array($interfaceName, class_implements($className)); 
     } 
    ); 
} 
3

Um zu überprüfen, die eine bestimmte Schnittstelle implementiert, können Sie eine Funktion wie unten schreiben:

<?php 
/** 
* Get classes which implement a given interface 
* @param string $interface_name Name of the interface 
* @return array Array of names of classes. Empty array means input is a valid interface which no class is implementing. NULL means input is not even a valid interface name. 
*/ 
function whoImplements($interface_name) { 
    if (interface_exists($interface_name)) { 
     return array_filter(get_declared_classes(), create_function('$className', "return in_array(\"$interface_name\", class_implements(\"\$className\"));")); 
    } 
    else { 
     return null; 
    } 
} 

Ausgabe eines Beispiels Aufruf var_export(whoImplements('ArrayAccess')); wie folgt sein:

[sandbox]$ php whoimplementswhat.php 
Array 
(
    [29] => CachingIterator 
    [30] => RecursiveCachingIterator 
    [38] => ArrayObject 
    [39] => ArrayIterator 
    [40] => RecursiveArrayIterator 
    [48] => SplDoublyLinkedList 
    [49] => SplQueue 
    [50] => SplStack 
    [55] => SplFixedArray 
    [56] => SplObjectStorage 
    [111] => Phar 
    [112] => PharData 
) 

+0

Auf diese Weise verwenden Sie keine Schleifen und Sie können den Code auf niedrigeren Versionen von PHP ausführen. –

+0

Haben Sie eine Idee, warum ich ein leeres Array sehe, obwohl ich definitiv die Schnittstelle implementiere? – Smalbil

+0

@Netbulae Es muss etwas falsch sein. Setzen Sie Ihren Code in Codepad und teilen Sie einen Link. –

Verwandte Themen