2011-12-14 1 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)은 정확하며이 중 3 개만 생성됩니다.

getStaticProperties은 (반드시) 정적 속성 만 가져오고 private $_value이 할당 된 유일한 위치는 생성자에 있습니다. 완전성을 위해 생성자는 생성자 내에서 3 번만 호출되며 예상대로 값은 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로 원래의 코드를 실행, 내가 그랬어 **하지 ** 재귀 메시지가 나타납니다. –

+0

버전이 나를 위해 작동하지 않습니다. 저는 PHP 5.2.4를 사용하고 있습니다. 사용중인 PHP 코드 뒤에 몇 가지 수정 사항이 있습니다. 나는 어떤 이슈가 inbetween로 고정되어 있어야한다고 가정하고 있습니다. 슬프게도 우리 프로덕션 버전에서 PHP를 업데이트 할 수는 없지만 적어도 최신 버전에서는 작동 할 것입니다. – MartijnCMT

+0

성능 측면. 반사 물건은 일회성 비용이므로 너무 나쁘지 않아야합니다. – MartijnCMT