2011-12-14 52 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