2010-10-22 16 views
21

Tengo una interfazPHP: ¿cómo obtener una lista de clases que implementan cierta interfaz?

interface IModule { 
    public function Install(); 
} 

y algunas clases que implementan esta interfaz

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

Cómo obtener una lista de todas las clases que implementan esta interfaz? Me gustaría obtener esta lista con PHP.

+2

Probablemente deberías aclarar si quieres obtener la lista dentro de PHP o simplemente quieres genere dicha lista para fines de documentación, etc. –

Respuesta

20

Puede utilizar ReflectionClass::implementsInterface y get_declared_classes funciones de PHP para lograr esto:

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

Nota: Esto no funciona si está cargando IModules mediante '__autoload'. Pero +1. –

+0

7 años de retraso en los comentarios, pero aquí hay un ejemplo de cómo puede usar los archivos de la carga automática de Composer para asegurarse de que algunos archivos específicos se carguen cada vez y estén disponibles con get_declared_classes: http://stackoverflow.com/a/18671530/143279 – bleakgadfly

40

Usted no necesita de la reflexión por esto. Usted puede simplemente utilizar

  • class_implements - Devolver las interfaces que son implementadas por la clase dada

Uso

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

Ejemplo 1 - Echo todas las clases que implementan la interfaz Iterator

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

Ejemplo 2 - array de retorno de todas las clases que implementan la interfaz Iterator

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

El segundo ejemplo requiere PHP5.3 debido a la devolución de llamada es una función anónima.

11

solución genérica:

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

Para comprobar que implementa una interfaz en particular, se puede escribir una función como la siguiente:

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

salida de un ejemplo de llamada var_export(whoImplements('ArrayAccess')); será el siguiente:

[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

De esta forma, no utiliza bucles y puede ejecutar el código en versiones inferiores de PHP. –

+0

¿Tiene alguna idea de por qué veo una matriz vacía, aunque definitivamente estoy implementando la interfaz? – Smalbil

+0

@Netbulae Debe haber algo mal. Pon tu código en el teclado y comparte un enlace. –

Cuestiones relacionadas