Получить все определенные классы родительского класса в php
Мне нужно определить, после того, как все файлы были включены, какие классы расширяют родительский класс, поэтому:
class foo{
}
class boo extends foo{
}
class bar extends foo{
}
и я хотел бы иметь возможность захватить массив вроде:
array('boo','bar');
Ответы
Ответ 1
Если вам это нужно, это действительно пахнет как плохой код, базовому классу не нужно знать это.
Однако, если вы включили определения (т.е. вам не нужно включать новые файлы с классами, которые у вас есть), вы можете запустить:
$children = array();
foreach(get_declared_classes() as $class){
if($class instanceof foo) $children[] = $class;
}
Ответ 2
Принимая Wrikken, ответьте и исправьте его с помощью предложения Scott BonAmi, и вы получите:
$children = array();
foreach( get_declared_classes() as $class ){
if( is_subclass_of( $class, 'foo' ) )
$children[] = $class;
}
Другие предложения is_a()
и instanceof
не работают для этого, потому что оба они ожидают экземпляр объекта, а не имя класса.
Ответ 3
Используйте
$allClasses = get_declared_classes();
чтобы получить список всех классов.
Затем используйте функцию PHP Reflection, чтобы построить дерево наследования.
Ответ 4
Я уверен, что следующее решение или что-то подобное будет хорошо подходить для вашей проблемы. ИМХО, вы можете сделать следующее (это своего рода шаблон наблюдателя):
1- Определите вызов интерфейса Fooable
interface Fooable{
public function doSomething();
}
2- Все ваши целевые классы должны реализовать этот интерфейс:
class Fooer implements Fooable{
public function doSomething(){
return "doing something";
}
}
class SpecialFooer implements Fooable{
public function doSomething(){
return "doing something special";
}
}
3- Сделайте класс регистратора, назовите его FooRegisterar
class FooRegisterar{
public static $listOfFooers =array();
public static function register($name, Fooable $fooer){
self::$listOfFooers[$name]=$fooer;
}
public static function getRegisterdFooers(){
return self::$listOfFooers;
}
}
4 Где-то в вашей загрузке script или некотором script, который включен в boot script:
FooRegisterar::register("Fooer",new Fooer());
FooRegisterar::register("Special Fooer",new SpecialFooer());
5- В вашем основном коде:
class FooClient{
public function fooSomething(){
$fooers = FooRegisterar::getRegisterdFooers();
foreach($fooers as $fooer){
$fooer->doSomthing();
}
}
}