Trey
Trey

Reputation: 5520

Get all defined classes of a parent class in php

I need to determine, after all files have been included, which classes extend a parent class, so:

class foo{
}
class boo extends foo{
}
class bar extends foo{
}

and I'd like to be able to grab an array like:

array('boo','bar');

Upvotes: 31

Views: 28567

Answers (4)

SteAp
SteAp

Reputation: 11999

Use

$allClasses = get_declared_classes();

to get a list of all classes.

Then, use PHP's Reflection feature to build the inheritance tree.

Upvotes: 7

Ahmad Hajjar
Ahmad Hajjar

Reputation: 1853

I am pretty sure that the following solution or some thing like that would be a good fit for your problem. IMHO, you can do the following (which is kind of observer pattern):

1- Define an interface call it Fooable

interface Fooable{
    public function doSomething();
}

2- All your target classes must implement that interface:

class Fooer implements Fooable{
    public function doSomething(){
         return "doing something";
    }
}

class SpecialFooer implements Fooable{
    public function doSomething(){
         return "doing something special";
    }
}

3- Make a registrar class call it the 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- Somewhere in your boot script or some script that is included in the boot script:

FooRegisterar::register("Fooer",new Fooer());
FooRegisterar::register("Special Fooer",new SpecialFooer());

5- In your main code:

class FooClient{

    public function fooSomething(){
         $fooers = FooRegisterar::getRegisterdFooers();
         foreach($fooers as $fooer){
              $fooer->doSomthing();
         }
    }
}

Upvotes: 3

MikeSchinkel
MikeSchinkel

Reputation: 5036

Taking Wrikken's answer and correcting it using Scott BonAmi's suggestion and you get:

$children = array();
foreach( get_declared_classes() as $class ){
  if( is_subclass_of( $class, 'foo' ) )
    $children[] = $class;
}

The other suggestions of is_a() and instanceof don't work for this because both of them expect an instance of an object, not a classname.

Upvotes: 32

Wrikken
Wrikken

Reputation: 70480

If you need that, it really smells like bad code, the base class shouldn't need to know this.

However, if you definitions have been included (i.e. you don't need to include new files with classes you possibly have), you could run:

$children  = array();
foreach(get_declared_classes() as $class){
    if($class instanceof foo) $children[] = $class;
}

Upvotes: 27

Related Questions