如何在PHP中按属性/常量名识别类

时间:2016-02-01 08:07:17

标签: php oop

我的代码看起来像这样:

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

我的客户端代码如下所示:

$class_id = DB::getClassId();

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

我想摆脱这个开关,并以某种方式调用 doSomething()方法,而不指定确切的类。我从DB加载了ID,我需要通过该ID获取一个类。我想我最有可能重新组织这段代码,但我现在已经没想到了。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

你不能直接这样做。使用“设置”中的功能。

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

答案 1 :(得分:1)

假设您的Setting类具有唯一值的constanstants和名称匹配的类名,您可以这样做:

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

然后如此:

$class_id = DB::getClassId();

$className = getClassNameById($class_id);

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

编辑:现在,函数假定查找类具有公共ID常量。