0

I have a system where I am creating multiple classes that all extend from an abstract class.

Each class also declares 'settings' for that particular class type.

Example:

class First extends Base {

    protected $name = 'First';
    protected $lug = 'first';
    protected $fields = [
        'name',
        'address',
        'phone',
    ];

    function __construct()
    {
        parent::__construct();
    }

    public function abstractMethod()
    {
        // do stuff for this particular class
    }


}

and

class Second extends Base {

    protected $name = 'Second';
    protected $lug = 'second-one';
    protected $fields = [
        'first-name',
        'last-name',
        'email',
    ];

    function __construct()
    {
        parent::__construct();
    }

    public function abstractMethod()
    {
        // do stuff for this particular class
    }


}

Now what I want to be able to do is grab all extended classes and their 'settings' and return something like this:

$classes = [
    'first' => [
        'name' => 'First',
        'slug' => 'first',
        'fields' => ['name', 'address', 'phone']
    ],
    'second' => [
        'name' => 'Second',
        'slug' => 'second-one',
        'fields' => ['first-name', 'last-name', 'email']
    ]
];

So how would I go about doing this? Is there a better way?

I am using Laravel if that helps.

Edit: To Explain why not a duplicate

I'm not just after a way to get classes and their information I am after a way to architect this situation. I am essentially creating an extensible plugin system and need a way to Tell-Don't-Ask which plugins have been added.

mattl
  • 2,082
  • 3
  • 17
  • 24
  • possible duplicate of [Get all extended Classes in PHP](http://stackoverflow.com/questions/16680040/get-all-extended-classes-in-php) – Luceos Jul 02 '15 at 09:16

3 Answers3

1

I didn't try it, but it should work. Or it'll directs you.

$result = array();
foreach (get_declared_classes() as $class) {
    if (is_subclass_of($class, 'Base'))
        $result[] = get_class_vars($class);
}

But your properties needs to be public also.

1

What about using ReflectionClass? Getting properties is quite easy, example from manual below. Listing extended classes should be easy too.

<?php
class Bar {
    protected $inheritedProperty = 'inheritedDefault';
}

class Foo extends Bar {
    public $property = 'propertyDefault';
    private $privateProperty = 'privatePropertyDefault';
    public static $staticProperty = 'staticProperty';
    public $defaultlessProperty;
}

$reflectionClass = new ReflectionClass('Foo');
var_dump($reflectionClass->getDefaultProperties());

Output:

array(5) {
   ["staticProperty"]=>
   string(14) "staticProperty"
   ["property"]=>
   string(15) "propertyDefault"
   ["privateProperty"]=>
   string(22) "privatePropertyDefault"
   ["defaultlessProperty"]=>
   NULL
   ["inheritedProperty"]=>
   string(16) "inheritedDefault"
}
long
  • 3,692
  • 1
  • 22
  • 38
  • Yeah ReflectionClass would be good, so I don't have to instantiate them as in ReflectionObject. – mattl Jul 02 '15 at 14:56
0

Using ReflectionObject you can do it like this:

$result = array();
foreach (get_declared_classes() as $class) {
    if (is_subclass_of($class, 'Base')) {
        $obj = new $class;
        $refObj = new ReflectionObject($obj);
        $props = $refObj->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED);
        $classProps = array();
        foreach ($props as $prop) {
            $property = $refObj->getProperty($prop->getName());
            $property->setAccessible(true);
            $classProps[$prop->getName()] = $property->getValue($obj);
        }
        $result[$class] = $classProps;
    }
}
print_r($result);

Output:

Array (
    [First] => Array (
        [name] => First
        [lug] => first
        [fields] => Array (
             [0] => name
             [1] => address
             [2] => phone
         )
     )
     [Second] => Array (
         [name] => Second
         [lug] => second-one
         [fields] => Array (
             [0] => first-name
             [1] => last-name
             [2] => email
         )
     )
)