在PHP中以编程方式引用类

时间:2013-05-25 11:47:56

标签: php class-reference

我在某个过程中收到一个对象,这个对象需要弄清楚它的着色方案。 例如,我有一个着色方案,存储方式如下:

class FirstScheme {
    public static $COLORS = array('1' => 'green', '2' => 'red', ...);
}
class SecondScheme {
    public static $COLORS = array('1' => 'red', '2' => 'green', ...);
}

我事先知道所有的着色方案名称;它们只能在代码更改时更改。 但是,需要在运行时通过匹配此对象的属性来确定要用于每个对象的着色方案。

在这里,我不知道该怎么做。在 python 中,我会定义一个包含颜色方案映射的字典,如下所示:

d = {'attr_value1': FirstScheme, 'attr_value2': SecondScheme, 'attr_value3': FirstScheme, ...}

然后只需访问"颜色"变量,因为每个类都应该有它。但是在 PHP 中,无法以这种方式引用类,那么正确的方法是什么? 请注意,多个属性可以映射到相同的着色方案。

3 个答案:

答案 0 :(得分:2)

如果每个类都应该有颜色,请定义允许它们获取的接口:

interface ColorsProvider {
    function getColors();
}
class FirstScheme implements ColorsProvider {
    public static COLORS = array('1' => 'green', '2' => 'red', ...);

    public function getColors() {
        return self::COLORS;
    }
}
class SecondScheme implements ColorsProvider {
    public static COLORS = array('1' => 'red', '2' => 'green', ...);

    public function getColors() {
        return self::COLORS;
    }
}

然后,你有一堆你的参数:

$a = array(
  'attr_value1' => new FirstScheme(),
  'attr_value2' => new SecondScheme(),
);

您可以致电:

$param = 'attr_value1';

if(!isset($a[$param]))
    throw new Exception("undefined param");

if(!($a[$param] instanceof ColorsProvider))
    throw new Exception("Param should point to ColorsProvider");

$a[$param]->getColors();

请注意,它是完全客观的。在PHP中有简单的方法来获得这种效果,但我的解决方案很优雅。


另一点是接口完全分离颜色的源。会有来自文件,数据库,xml,硬编码等。


默认实施可能是:

abstract class DefaultColorsProviderImpl implements ColorsProvider             {
    protected static COLORS = array();

    public function getColors() {
        return self::COLORS;
    }
}

class FirstScheme extends DefaultColorsProviderImpl {
    protected static COLORS = array( ... );
}

但仍允许进行从e.x返回颜色的泛型实现。来自档案。

答案 1 :(得分:1)

在自己的类中对颜色进行硬编码的替代方法是以下方法:

class ColorScheme {

   protected $colors;

   public function __construct(array $colors) {
       $this->colors = $colors;
   }

   public function getColors() {
       return $this->colors;
   }

}

$scheme1 = new ColorScheme(array('red', 'blue', 'green'));
$scheme2 = new ColorScheme(array('yellow', 'pink', 'cyan'));

PHP中python字典的等价物是一个关联数组。所以你可以这样做:

$d = array (
    'values_1' => $scheme1->getColors(),
    'values_2' => $scheme2->getColors()
);

答案 2 :(得分:1)

当然你可以:

$schemes = [
  'attr_value1' => FirstScheme::$COLORS,
  'attr_value2' => SecondScheme::$COLORS,
  ...
];

甚至在运行时:

$schemes = [
  'attr_value1' => 'FirstScheme',
  'attr_value2' => 'SecondScheme',
  ...
];

然后:

$reflector = new ReflectionClass($schemes['attr_value1']);
$schema = $reflector->getStaticPropertyValue('COLORS');

但这似乎根本不可维护,并且您希望将这些信息存储在适当的数据层中,而不将它们硬编码为类的静态字段[这不是它们的目的]。