我有一个界面
interface IModule {
public function Install();
}
Run Code Online (Sandbox Code Playgroud)
以及一些实现此接口的类
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;
}
}
Run Code Online (Sandbox Code Playgroud)
如何获取实现此接口的所有类的列表?我想用PHP获取这个列表.
Gor*_*don 50
你不需要反思.你可以简单地使用
class_implements
- 返回给定类实现的接口 用法
in_array('InterfaceName', class_implements('className'));
Run Code Online (Sandbox Code Playgroud)
示例1 - 回显实现Iterator接口的所有类
foreach (get_declared_classes() as $className) {
if (in_array('Iterator', class_implements($className))) {
echo $className, PHP_EOL;
}
}
Run Code Online (Sandbox Code Playgroud)
示例2 - 返回实现Iterator接口的所有类的数组
print_r(
array_filter(
get_declared_classes(),
function ($className) {
return in_array('Iterator', class_implements($className));
}
)
);
Run Code Online (Sandbox Code Playgroud)
第二个例子需要PHP5.3,因为回调是一个匿名函数.
Jac*_*kin 27
您可以使用PHP ReflectionClass::implementsInterface
和get_declared_classes
函数来完成此任务:
$classes = get_declared_classes();
$implementsIModule = array();
foreach($classes as $klass) {
$reflect = new ReflectionClass($klass);
if($reflect->implementsInterface('IModule'))
$implementsIModule[] = $klass;
}
Run Code Online (Sandbox Code Playgroud)
Jer*_*auw 13
通用解决方案:
function getImplementingClasses( $interfaceName ) {
return array_filter(
get_declared_classes(),
function( $className ) use ( $interfaceName ) {
return in_array( $interfaceName, class_implements( $className ) );
}
);
}
Run Code Online (Sandbox Code Playgroud)
要检查谁实现了特定接口,您可以编写如下函数:
<?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;
}
}
Run Code Online (Sandbox Code Playgroud)
示例调用的输出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
)
Run Code Online (Sandbox Code Playgroud)
这样,您就无需使用循环,并且可以在较低版本的 PHP 上运行您的代码。函数在array_filter
内部循环,但在 PHP 执行引擎内部(因此比用 PHP 代码编写的循环性能更高)。
The answers here don't actually suggest any reliable way to achieve this... while they do work, they are unreliable in the sense that they're only returning classes that have been loaded, which is not what anyone really wants and is redundant to instanceof
in the scenarios that these methods are potentially useful for.
get_declared_classes()
Returns an array of the names of the declared classes in the current script.
The keyword here is current script
, this function will not return classes that have not been loaded yet.
interface_exists
Similar to the above, this method will not know if an interface exists, if the interface has not been loaded yet.
它还会自动加载界面(注意第二个参数interface_exists
)
class_implements
与上面类似,无论您打算使用它们,这也会自动加载您的文件。
简而言之,用所有这些信息构建一个清单并将其存储在缓存中。
清单有助于缓存信息,但在每个请求上生成这些信息的成本太高。一些清单生成映射,例如类名到文件系统位置。其他存储聚合信息,例如嵌套配置图。
这是在 MVC 中构建清单的一个很好的示例,它纯粹用于解决上述问题。
准确地实现类清单需要考虑相当多的代码,并且在这个答案中发布完整的图片会有点困难,但是这里有一些参考点可以帮助您开始:
上面的实现是使用了nikic/php-parser
包,而不是直接使用反射。
归档时间: |
|
查看次数: |
16693 次 |
最近记录: |