2013-03-15 6 views
4

배열을 객체로 변환하려고합니다. 정적 속성을 가진 __get 및 __set과 같은 마법 메서드를 사용하고 싶습니다.PHP 정적 클래스에서 마법 메서드를 사용하는 방법?

내 코드 :

class UserData { 
    private static $id, $name, $login; 

    public function __get($var) 
    { 
     return self::$var; 
    } 
    public function __set($var, $val) 
    { 
     self::{$var} = $val; 
    } 
} 

및 설정 :

foreach($userArray as $key => $val) 
    { 
     DaneBilingowe::${$key} = $val; 
    } 

오류 : 치명적인 오류 : Private 속성 UserData를 :: $ 아이디

에 액세스 할 수 없음이 가능 마법 방법을 사용하는 것입니다 정적 속성?

+0

[PHP 매뉴얼] (http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members) :'Property 오버로딩은 객체 컨텍스트에서만 작동합니다. (...) 정적 컨텍스트에서 트리거되지 않습니다.'꽤 많이 합계. –

+0

@Alvin 정적 컨텍스트에 대한 컨텍스트가있는 경우 정적 컨텍스트에 액세스 할 수 있습니다. 말도 안되지만 가능합니다. 내 대답 좀 봐. – Ihsan

+0

"'DaneBilingowe :: $ {$ key} = $ val;'"- 실제로 각 사용자에 대한 하위 클래스를 만들었습니까? 그것이 바로 인스턴스입니다. '$ daneBillingowe = 새로운 UserData ('Dane Billingowe'); - 문제가 해결 되었습니까? –

답변

4

간단히 말해서, 아니오.

__get()__set()은 인스턴스 메소드입니다. 그들은 본질적으로 인스턴스 인 stdClass()을 구성하는 함수입니다.

정적 콘텐츠를이 방식으로 설정해야하는 경우 클래스에 stdClass 매개 변수와 마술처럼 설정하고 데이터를 가져올 수있는 단일 구조를 제공 할 수 있습니다. 예를 들어

:

class UserData { 
    protected static $_instance; 
    protected $_data = array(); 

    public static function get_instance() { 
     static $initialized = FALSE; 

     if (! $initialized) { 
      self::$_instance = new UserData; 
      $initialized = TRUE; 
     } 

     return self::$_instance; 
    } 

    public function __get($var) { 
     $self = self::get_instance(); 

     return isset($self->_data[$var]) ? $self->_data[$var] : NULL; 
    } 

    public function __set($var, $val) { 
     $self = self::get_instance(); 

     $self->_data[$var] = $val; 
    } 
} 

그런 다음 당신은 갈 수있다 : 그들은 무의미하기 때문에

$UserData =& UserData::get_instance(); 
$UserData->var = 'val'; 

echo $UserData->var; // prints 'val' 

그러나 나는 PHP에서 싱글 톤을 사용하지 않는 것이 좋습니다. 왜 Best practice on PHP singleton classes 게시물에 몇 가지 이유를 읽을 수 있습니다.

정적 클래스 또는 인스턴스 클래스를 사용하십시오.

매직 게터 및 설정자는 바로 가기입니다. 일반 setter 및 getter에서 동일한 동작을 구현할 수 있습니다. 아래의 예는 동일한 기능을 제공하지만 의도는 훨씬 더 분명하다 : 위의 코드 $ ID를 쓸 수 없습니다 얼마나

class UserData { 
    protected $id, $name, $login; 

    public static function set_name($name) { 
     self::$name = $name; 
    } 

    public static function set_login($login) { 
     self::$login = $login; 
    } 

    public static function get_id() { 
     return self::$id; 
    } 

    public static function get_name() { 
     return self::$name; 
    } 

    public static function get_login() { 
     return self::login; 
    } 
} 

알 수 있습니다. 그것은 읽기만 가능합니다. $ name과 $ login은 읽고 쓸 수 있습니다. 일반 setter 및 getter를 사용하여 읽기 및 쓰기를 제어하는 ​​것이 더 쉽고 덜 버그 있습니다. 매직 방법은 단지 마법이며, 일반적으로 마법은 구체적이지 않으며 코드에서 이해하기 쉽지 않습니다.

내가 원하는 마지막 요소는 왜 UserData가 정적일까요? 코드 전체에서 1 명의 사용자 만있는 경우가 아니라면 정적 인 코드를 사용하는 것이 좋습니다. 아마도 전체 그림을 얻지는 못 하겠지만 ID와 이름이있는 인스턴스를 인스턴스화해야 여러 인스턴스를 가질 수 있습니다. 그렇지 않으면 클래스 자체가 고유하기 때문에 왜 ID를 가지게 되는가?

4

정적 속성에서 실제로 마법 메서드를 사용하려면 인스턴스가 필요합니다. 비록 그것이 합리적이지는 않지만, 프로그래머 자체가 전혀 합리적이지 못하다. :)

또한 사용자 정의 클래스와 객체는 PHP에서 동적이지 않다. 당신은 쉽게 그 변수를 추가 할 수 없습니다 ... 그래서 당신은 아래의 패턴을 사용할 수 있습니다

class UserData { 
    private static $id, $name, $login, $arr = []; 

    public function __get($var){ 
     return (array_key_exists(self::$arr, $var)? self::$arr[$var]:null; 
    } 

    public function __set($var, $val){ 
     self::$arr[$var] = $val; 
    } 
} 

및 설정 : 음 DaneBilingowe 무엇입니까? 나는 지금 여기 없어 ...하지만 :

$inst = new UserData(); 

foreach($userArray as $key => $val){ 
    $inst->$key = $val; 
} 

이 적용됩니다.

하지만 클래스 (고정) 메모리에서만 작동합니다. 또한 이름 설정에 적절한 필터링이 없기 때문에 이상한 일이 발생할 수 있습니다. (추가해야 함을 의미)

관련 문제