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.
Ответы
Ответ 1
Вы можете использовать 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;
}
Ответ 2
Вам не нужно Reflection для этого. Вы можете просто использовать
Использование
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 из-за того, что обратный вызов является анонимной функцией.
Ответ 3
Общее решение:
function getImplementingClasses( $interfaceName ) {
return array_filter(
get_declared_classes(),
function( $className ) use ( $interfaceName ) {
return in_array( $interfaceName, class_implements( $className ) );
}
);
}
Ответ 4
Чтобы проверить, кто реализует конкретный интерфейс, вы можете написать функцию, как показано ниже:
<?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'));
будет следующим:
[песочница] $ php whoimplementswhat.php
массив
(
[29] => CachingIterator
[30] => RecursiveCachingIterator
[38] => ArrayObject
[39] => ArrayIterator
[40] => RecursiveArrayIterator
[48] => SplDoublyLinkedList
[49] => SplQueue
[50] => SplStack
[55] => SplFixedArray
[56] => SplObjectStorage
[111] => Фар
[112] => PharData
)
Таким образом, вы не используете циклы и можете запускать свой код на более низких версиях PHP. Функция array_filter
зацикливается внутри, но внутри механизма исполнения PHP (следовательно, более производительная, чем циклы, написанные в коде PHP).