2013-09-04 3 views
1

__set()__get() 마법 메서드를 사용하는 간단한 클래스의 두 가지 예제가 있습니다. 하나는 치명적인 오류를 던지고 다른 하나는 unset() 기능으로 보호 된 속성에 액세스하려고 시도하지 않습니다. 동적으로 속성 이름을 만들 때 PHP 마법 메서드가 다르게 동작합니다

예 1에서, 내 보호 특성 밑줄를 시작하고 친숙한 이름을 통해 액세스 할 수 있도록 내 __set()__get() 방법에 밑줄을 붙이는 명명하고있다. (밑줄없이 속성을 효과적으로 노출).

예 2에서 나는 밑줄로 이름을 시작하고 __set()__get() 방법에 직접 이름을 통해 액세스 할 수 있도록 하지입니다.

질문

1) 왜 예 1 예 2 치명적인 오류가 발생 않지만 치명적인 오류가 발생하지 않는 이유는 무엇입니까? 나는 둘 다 오류를 던지거나 둘 다 오류를 던질 것으로 기대합니다.

2) 또한, 예제 1은 이 아니며은 실제로 속성을 설정 해제합니까? 난 unset() 함수가 호출 된 후 속성 값을 포함하지 기대하고있다.

예 1

class Example { 

    protected $_my_property; 

    function __get($name) { 
     echo '<h4>__get() was triggered!</h4>'; 
     $name = '_' . $name; 
     if (property_exists($this, $name)) { 
      return $this->$name; 
     } 
     else { 
      trigger_error("Undefined property in __get(): $name"); 
      return NULL; 
     } 
    } 

    function __set($name, $value) { 
     echo '<h4>__set() was triggered!</h4>'; 
     $name = '_' . $name; 
     if (property_exists($this, $name)) { 
      $this->$name = $value; 
      return; 
     } 
     else { 
      trigger_error("Undefined property in __set(): {$name}"); 
     } 
    } 

} 

$myExample = new Example(); 
$myExample->my_property = 'my_property now has a value'; 
echo $myExample->my_property; 
unset($myExample->my_property); 
echo "Did I unset my property?: {$myExample->my_property}"; 

예 2

보조 노트로
class Example { 

    protected $my_property; 

    function __get($name) { 
     echo '<h4>__get() was triggered!</h4>'; 
     if (property_exists($this, $name)) { 
      return $this->$name; 
     } 
     else { 
      trigger_error("Undefined property in __get(): $name"); 
      return NULL; 
     } 
    } 

    function __set($name, $value) { 
     echo '<h4>__set() was triggered!</h4>'; 
     if (property_exists($this, $name)) { 
      $this->$name = $value; 
      return; 
     } 
     else { 
      trigger_error("Undefined property in __set(): {$name}"); 
     } 
    } 

} 

$myExample = new Example(); 
$myExample->my_property = 'my_property now has a value'; 
echo $myExample->my_property; 
unset($myExample->my_property); 
echo "Did I unset my property?: {$myExample->my_property}"; 

, 이것은 내가 내 실제 프로젝트에서보고 있어요 동작을 보여줍니다 그냥 단순한 예입니다 . 감사!

+0

속성 선언을 포함하면 질문이 더 명확해질 것이라고 생각합니다. 이 동작은 속성 중 하나를 초기화하지 않아서 쉽게 발생할 수 있습니다. –

+0

@SamDufel 고마워요,하지만 당신이 의미하는 바를 이해하지 못했습니다. 내 코드 샘플에서는 클래스 내부의 보호 된 속성을 'protected $ _my_property;'로 선언하고이를 클래스 외부에서 '$ myExample-> my_property ='my_property에 값 ';'이있는 것으로 초기화했습니다. –

+0

죄송합니다, 분명히 나는 ​​아침에 눈이 멀다. –

답변

2

문제는 __unset() 마법 방법을 정의하지 않았다는 것입니다.

즉, unset($myExample->my_property)을 호출하면 지정된 이름으로 공용 속성을 직접 설정 해제하려고 시도하고 있음을 의미합니다.

예제 1에서 실제 보호 속성에는 이름에 밑줄이 있습니다. 따라서 속성을 설정 해제하려고하면 PHP는 객체를보고 지정된 이름을 가진 것이 아무것도없는 것을보고 효과적으로 무시합니다.

존재하지 않는 변수 또는 배열 요소의 설정을 해제하려고 시도한 경우와 동일한 동작 인 unset()이 나타납니다.

그러나 예제 2에서 보호 된 속성의 이름은 unset() 호출에서 지정한 이름과 같습니다.

이 예제에서 PHP는 객체를보고 속성이 존재하지만 액세스 할 수 없음을 확인합니다. 따라서 속성을 해제 할 수 없다는 오류가 발생합니다.

당신은 당신의 __get()__set() 방법과 함께 __unset() 방법을 포함하여이 문제를 해결할 수 있습니다.마법 방법을 사용하려는 경우 이상적으로 세 가지를 모두 정의해야합니다.

희망이 있습니다.

+0

훌륭한 설명, 고맙습니다! 네,'__unset()'마법 메서드를 추가하고 같은 패턴을 따릅니다. –