gradosevic
gradosevic

Reputation: 5056

How to recognize class by property/constant name in PHP

My code looks something like this:

class Setting
{
    const SETTING_RED = 1;
    const SETTING_BLUE = 2;
}

class CLASS_A
{
    const ID = Setting::SETTING_RED;

    public static function doSomething(){
        //does something
    }
}

class CLASS_B
{
    const ID = Setting::SETTING_BLUE;

    public static function doSomething(){
        //does something different
    }
}

My client code looks something like this:

$class_id = DB::getClassId();

switch($class_id){
  case Setting::SETTING_RED: 
      CLASS_A::doSomething();
         break;
  case Setting::SETTING_BLUE: 
      CLASS_B::doSomething();
         break;
}

I want to get rid of this switch and somehow to call doSomething() method in general, without specifying the exact class. I have ID loaded from DB and I need to get a class by that ID. I guess I need most likely to reorganized this code, but I'm out of idea right now. Any ideas?

Upvotes: 1

Views: 57

Answers (2)

Aleksey Ratnikov
Aleksey Ratnikov

Reputation: 569

Assuming your Setting class has constanstants with unique value and names matching class names you may do so:

function getClassNameById($id){
    $userClassesList = array_filter(get_declared_classes(), function($className){
        // leave only user defined classes excluding Settings
        return !(new ReflectionClass($className))->isInternal() || $className == 'Setting';
    });

    foreach ($userClassesList as $className){
        $reflectionClass = new ReflectionClass($className);
        if ($reflectionClass->getConstant('ID') == $id) return $className;
    }

    return null;
}

And then so:

$class_id = DB::getClassId();

$className = getClassNameById($class_id);

if (class_exists($className)){
    $className::doSomesing();
}

Edit: Now function assumes that lookup classes have public ID constant.

Upvotes: 1

Jeremy
Jeremy

Reputation: 279

You can't do this directly. Use a function in Settings.

class Setting
{
    const CLASS_A = 1;
    const CLASS_B = 2;

    public static function getClass($id) {
        switch($id){
          case self::CLASS_A: 
              return 'CLASS_A';
              break;
          case self::CLASS_B: 
              return 'CLASS_B';
              break;
        }
        return false;
    }
}

class CLASS_A
{
    const ID = Setting::CLASS_A;

    public static function doSomething(){
        //does something
        echo "a";
    }
}

class CLASS_B
{
    const ID = Setting::CLASS_B;

    public static function doSomething(){
        //does something different
        echo "b";
    }
}


$class_id = 1;
$class = Setting::getClass($class_id);
if($class !== false) {
    echo $class::doSomething();
}

Upvotes: 1

Related Questions