2010-10-22 156 views
21

我有一个接口PHP:如何获得实现某个接口的类的列表?

interface IModule { 
    public function Install(); 
} 

和实现这个接口

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

如何获得实现此接口的所有类的列表中某些类? 我想用PHP获取这个列表。

+2

你应该澄清一下你是想在PHP中获取列表还是只想生成这样的列表用于文档目的等。 – 2010-10-22 04:01:39

回答

20

您可以使用PHP的ReflectionClass::implementsInterfaceget_declared_classes功能来实现这一点:

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

注意:如果您通过'__autoload'加载IModules,则这不起作用。但+1。 – 2010-10-22 04:14:25

+0

7年后发表评论,但这里是一个如何在Composer自动加载中使用文件的例子,以确保每次加载一些特定的文件,并可用于get_declared_classes:http://stackoverflow.com/a/18671530/143279 – bleakgadfly 2017-03-02 09:00:14

40

你不需要为此反思。你可以简单地使用

使用

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

例1实现的接口 - 回声实现Iterator接口所有类

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

实施例2 - 的所有类的返回阵列实施Iterator接口

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

第二示例需要PHP5.3由于回调是匿名函数。

11

通用的解决方案:

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

要检查谁实现了特定的接口,你可以编写一个函数象下面这样:

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

的示例调用var_export(whoImplements('ArrayAccess'));会随着产量如下:

[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

这样,您不使用循环,并且可以在较低版本的PHP上运行代码。 – 2013-11-06 09:05:35

+0

你知道为什么我看到一个空数组,但我确实在实现这个接口吗? – Smalbil 2014-06-28 23:43:59

+0

@Netbulae一定有什么问题。将代码放入键盘并共享链接。 – 2014-07-02 09:20:46

相关问题