oop – Get all defined classes of a parent class in php-ThrowExceptions

Exception or error:

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');
How to solve:

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

Answer:

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.

Answer:

Use

$allClasses = get_declared_classes();

to get a list of all classes.

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

Answer:

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

Leave a Reply

Your email address will not be published. Required fields are marked *