2011-12-14 54 views
1

我试图找到一种方法来处理PHP中的枚举。 我发现的方法都不能实际使用枚举来限制函数/方法的参数,这是我想要枚举的主要原因。使用PHP反射来建立枚举

于是我开始尝试创建自己的,但现在已经使用反射碰到一个问题:

<?php 

class Enum { 
    private $_value; 
    protected function __construct($value) { 
     $this->_value = $value; 
    } 

    public function getValue() { 
     return $this->_value; 
    } 

    protected static function enumerate($class) { 
     $ref = new ReflectionClass($class); 
     $instances = array(); 
     foreach ($ref->getStaticProperties() as $name => $value) { 
      $ref->setStaticPropertyValue($name, new $class($value)); 
     } 
    } 
} 

class Book extends Enum { 
    public static $COMIC = 1; 
    public static $NOVEL = 2; 
    public static $EDUCATIONAL = 3; 

    public static function enumerate() { 
     parent::enumerate(__CLASS__); 
    } 
} 
Book::enumerate(); 

function read(Book $book) { 
    echo '<hr/>'; 
    var_dump($book); 
} 

read(Book::$COMIC); 
read(Book::$EDUCATIONAL); 

?> 

我预期的输出显示两个预订,它们各自的值对象,而不是我得到这个:

object(Book)#2 (1) { ["_value:private"]=> object(Book)#2 (1) { ["_value:private"]=> *RECURSION* } } 
object(Book)#4 (1) { ["_value:private"]=> object(Book)#4 (1) { ["_value:private"]=> *RECURSION* } } 

进入setStaticPropertyValue的值(new $class)是正确的,并且仅创建其中的三个。

getStaticProperties只拾取静态属性(因为它应该)并且private $_value被分配的唯一位置在构造函数中。 为了完整起见,构造函数只被调用了三次,并且在构造函数中,该值与预期的一样,只有1,2或3次。总之,在调用setStaticPropertyValue之前,一切似乎都很完美。

我无法弄清楚这里发生了什么。 private $_value在哪里以及为什么分配了这个错误的值?我是否以错误的方式使用反射?什么是创建这些无限递归对象?

回答

1

这很迷人。当我遇到推动PHP界限的事物时,我喜欢它。

不过,我不得不说,这似乎有点极端,取决于反射速度有多快,它可能会相当缓慢。

对于我写的框架,我创建了一个简单的enum function。它所做的就是自动化定义。我更喜欢你的方法,因为你可以键入限制。

您的代码适用于我。我在下面发布我的编辑 - 他们主要是格式更改,所以我可以更容易地阅读它。

看看我对它做了什么。我用5.3.5和5.2.17测试了这一点 - 在任何一个上都可以正常工作。

<?php 
header('content-type: text/plain'); 

Book::enumerate(); 
Book::$COMIC->read(); 
read(Book::$EDUCATIONAL); 
read(Book::$NOVEL); 

class Enum 
{ 
    private $_value; 
    protected function __construct($value) 
    { 
     $this->_value = $value; 
    } 

    public function getValue() 
    { 
     return $this->_value; 
    } 

    protected static function enumerate($class) 
    { 
     $ref = new ReflectionClass($class); 
     $instances = array(); 

     foreach ($ref->getStaticProperties() as $name => $value) 
     { 
      $ref->setStaticPropertyValue($name, new $class($value)); 
     } 
    } 
} 

class Book extends Enum 
{ 
    public static $COMIC = 'comic'; 
    public static $NOVEL = 'novel'; 
    public static $EDUCATIONAL = 'edu'; 

    public static function enumerate() 
    { 
     parent::enumerate(__CLASS__); 
    } 
    public function read() 
    { 
     echo "\nReading a {$this->getValue()} book\n"; 
    } 
} 

function read(Book $book) 
{ 
    echo "\nReading a {$book->getValue()} book\n"; 
} 

输出

Reading a comic book 

Reading a edu book 

Reading a novel book 
+0

当与执行的var_dump你的原代码,我也没有** **收到递归消息。 – 2011-12-14 19:39:32