2010-07-31 5 views
4

나는 잘 돌아 다니며이 문제에 대한 답을 찾지 못하는 것 같습니다.메서드에서 보호 된 변수 선언하기

기본적으로 변수를 선언 할 때 _call 메서드를 사용하여 동적으로 get 및 set 메서드를 생성하지만 PHP 기본값은 public입니다. 어쨌든 클래스 내에서 변수를 보호 된 것으로 선언 할 수 있습니까?

function __call($method, $arguments) { 
    $prefix = strtolower(substr($method, 0, 3)); 
    $property = strtolower(substr($method, 3)); 

    if (empty($prefix) || empty($property)) { 
     return; 
    } 

    if ($prefix == "get" && isset($this->$property)) { 
     return $this->$property; 
    } 

    if ($prefix == "set") { 

     $this->$property = $arguments[0]; 
    } 
} 
+0

왜, 왜 __get 및 __set 대신 __call을 사용하고 있습니까? –

+0

그냥 쉽게 보였습니다. 여기에서 복사했습니다. http://onlamp.com/pub/a/php/2005/06/16/overloading.html –

답변

6

하나의 옵션은 보호 된 배열을 가지며 마법 설정자로부터 해당 배열의 요소를 설정하는 것입니다. 접두사 또는 재산 변수가 설정되지 않은 경우

class MyClass { 
    protected $_myProperties = array(); 

    public function __get($name) { 
     if (isset($this->_myProperties[$name])) { 
      return $this->_myProperties[$name]; 
     } else { 
      return null; 
     } 
    } 

    public function __set($name, $value) { 
     $this->_myProperties[$name] = $value; 
    } 

    public function __isset($name) { 
     return isset($this->_myProperties[$name]); 
    } 
} 
+0

감사합니다. 완벽하게 작동하지만 호출 메서드를 $ class-> getSomething(); –

2

보호와 같은 클래스 내에서 변수를 선언 어쨌든이 있나요?

그렇게 보이지 않습니다. Reflection에서 change the accessibility of properties까지 사용할 수 있지만 이전에 공개되지 않은 항목을 공개하는 데만 효과적으로 사용될 수 있습니다.

자동으로 생성 된 속성을 적절한 가시성을 가진 배열에 저장하는 것이 좋습니다.

(또한 __get__set있다,하지만 그들은 필요에 맞게하지 않을 수 있습니다. 그들은 단지 전화를받을 거라고 속성을 우회 할 보호 특성을 접촉 할 수있는 또는 액세스 할 수 없습니다. 클래스 없을 때.)

+0

예, 두 번째 단락에 동의합니다. 다음을 저장하십시오. _generated_ 연관 배열의 '속성'. 그러면 연관 배열은 클래스의 보호 된 속성이 될 수 있습니다. '__get' 또는'__set'을 사용하려면 _ 이렇게 생각해야합니다. – MrWhite

+0

나는 동의하지 않는다. 이것은 멤버 변수의 포인트를 무효화합니다. 클래스가 알려지지 않은 변수를 저장할 때 연관 배열을 사용합니다 (예 : 레지스트리 클래스 또는 이와 유사한 것). 그러나 알려진 변수의 수가 제한되어있을 때 멤버 변수를 사용하여 설계된 요소를 사용하지 않는 이유는 무엇입니까? – ircmaxell

+0

나는 질문에서, 그가 어떤 종류의 엉뚱한 상속 및/또는 시야 마술을하고 있다고 상상할 수 있습니다. 위에 게시 된 코드가 불완전하지 않으면 속성에 수행 된 변환이 표시되지 않습니다 ... – Charles

5

첫째을, 나는 높게 returning하지 좋을 것. 그것은 디버깅을 매우 어렵게 만들 것입니다. 대신 return;throw new BadMethodCallException('Method Does Not Exist: '.$method);

으로 바꾸십시오. 두 번째로 보호되는 변수를 무시하는 것이 아닙니까? 어떤 종류의 유효성 검사없이 모든 속성을 읽고 쓸 수 있습니다. 당신이 이것을하려고한다면, 당신은 대중에게 공개 할 수도 있습니다.

저는 개인적으로 $foo->setBar('baz');보다 읽기 쉽도록 $foo->bar = 'baz';을 찾습니다. 이해하기가 쉽지 않기 때문에가 아니라 두 번째가 불필요하게 길기 때문입니다.

개인적으로는 __get__set 일을 제안하고 유효성을 추가하는 것이 좋습니다. 변수 보호의 요점은 신뢰를위한 것입니다 (그래서 당신은 설정을 신뢰할 수 있습니다). 물론, 당신은 반성이나 하위 분류를 사용하여 그것들을 바꿀 수 있지만, 나는 누군가가 그렇게까지 간다면 변수를 망쳐 놓는 경우 의도하지 않은 개념을 가질 가치가 있다고 생각합니다.

그리고 당신은 마법 방법의 어떤 종류를 사용하는 경우, 당신은 당신이 당신의 IDE는 방법을 암시하려는 경우 문서 요소를 추가해야한다는 점을 명심/당신에게 변수 ...

편집 :

__get/__set 메서드를 선언하면 하위 클래스에서 재정의 할 수 있습니다. 따라서 새 변수를 선언하면 하위 변수를 처리하고 parent::__get을 호출하여 기본 변수를 처리 할 수 ​​있습니다. 배열로 이동하지 마십시오. 그러면 모든 자식에 대해 하나의 메서드를 가질 수 있습니다. 귀하가 알고있는 회원들에 대한 검증을 수행하고 자녀들이 자신의 확인을 처리하게하십시오 ...

+2

+1 $ foo-> setBar ('baz');에 동의하지 마십시오. $ foo-> bar = 'baz'와 비교하여 불필요하게 verbode되고 있습니다. getter 및 setter 메서드는 항상 속성 설정에 대한 유효성 검사를 허용하기 때문에 비공개 속성은 항상 유효성 검사를 거치지 않고 설정할 수 있기 때문에 ... 여기에 정보의 매우 유용한 스 니펫 –

+0

많은 변수에 대한 대체 방법 일뿐입니다. 수업에 추가해야합니다. 일반적으로 나는 항상 보호 된 변수에 필요한 경우 get 및 set 메서드를 사용합니다. 디버깅에 대한 어려움을 완전히 이해하고이 방법을 드물게 사용하여 DRY를 달성 할 것입니다. –

+0

글쎄, 나는 때때로'getBar()'구문을 사용하지만 실제로 이해가되지 않는 한 시도하지 않는다. 나는 단지 멤버 변수를 가져 오거나 설정하기위한 클래스에서 50 개의 메소드를 가지고있는 것이 혼란스럽지 않다 ... 대부분의 경우 단순히 필요하지는 않다. (항상 그런 것은 아니다) ... – ircmaxell