2013-02-19 8 views
1

다음 코드를 발견했기 때문에 PHP의 get 및 set 마법 메서드를 사용하여 직관적이지 않은 시퀀스에서 스크립트의 출력이 나오는 이유를 알 수 없었습니다. 풋 아웃PHP 객체 지향 과부하

class Magic 
{ 
    public $a = "A"; 
    protected $b = array("a" => "A", "b" => "B", "c" => "C"); 
    protected $c = array(1,2,3); 

    public function __get($v) 
    { 
     echo "$v"; 
     return $this->b[$v]; 
    } 
    public function __set($var, $val) 
    { 
     echo "$var: $val"; 
     $this->$var = $val; 
    } 
} 
$m = new Magic(); 
echo $m->a . "," . $m->b . "," . $m->c . ","; 
$m->c = "CC"; 
echo $m->a . "," . $m->b . "," . $m->c; 

했다 : 모든

bcA,B,C,c 
CCbcA,B,C 

먼저 왜 제일 먼저는 어떠한 출력 A를인가? 출력 순서가 의미가 없습니다.

+3

지긋 지긋한 var 및 값에 의미있는 이름을 지정하십시오. 눈으로 보는 것이 고통 스럽습니다. – moonwave99

답변

1

이유는 매우 간단합니다. 문자열 연결을 수행하므로 PHP는 출력 전에 완전한 문자열을 준비해야합니다. 연결되어야하는 모든 것을 실행한다는 의미입니다. getter (__get 메서드는 액세스 할 수없는 멤버에 대해서만 호출됩니다)을 실행하면 echo이 먼저 실행 된 다음 반환 된 값이 있습니다.

별도로 에코를 적용하면 모든 것이 제자리에있게됩니다.

+0

그래서 전체 평가를 출력하기 전에 일종의 "사전 처리"를 수행한다고 말할 수 있습니다. –

+0

@robertrocha 정확합니다. 문자열이 연결된 연산자의 왼쪽에있는 문자열을 연결하면 오른쪽의 문자열로 연결됩니다. 두 문자열이 모두 알려지지 않으면 인터프리터는 다른 문자열과 병합해야하는 문자열이 무엇인지 알아 내지 않으면 인터프리터는이를 연결할 수 없습니다. – Leri

+0

나는 그것이 지금 어떻게 작동 하는지를 이해한다고 생각한다. 코드 행이 평가됩니다. get, set 메소드는 전체 라인이 에코되기 전에 에코를 실행하기 때문에,이 두 메소드가 바이 패스 되었기 때문에 디스플레이의 순서가 뒤섞이는데, 여러분은 부모 에코가 자신 에코로 표시 될 수 있습니다. –

1

누군가가 자신의 젠드 인증 ;-)

이유에 대해 공부하는 것은 마술 방법에만 property is inaccessible 때를 유발한다는 것이다.

첫 번째 메아리의 경우 $m->a 이것은 접근 가능한 속성이므로 __get에서 반향되지 않으며 단순히 반환됩니다. 이 후 $b$c 모두 액세스 할 수 없으므로 에코 된 다음 반환됩니다.

은 그래서 첫 번째 에코의 출력은 다음과 같습니다

b // echo'd by __get 
c // echo'd by __get 
A // simply returned, and echo'd in the concatenated string 
B // (As above) 
C // (As above) 
+0

아주 미묘한 코드 조각. 설명서에서 설명조차하지 않았습니다. –

0
echo $m->a . "," . $m->b . "," . $m->c . ","; 

이 줄이 호출되면 연결을 수행하기 전에 먼저 변수 이름을 확인합니다.

그래서 $ m-> a, $ m-> b, $ m-> c를 찾습니다.

$ m-> a가 공개 속성 a로 변경되었으므로 _get을 트리거하지 않으므로 거기에 에코가 바로 전송되지 않습니다. 그러나 $m->b이 트리거하면 에코가 발생합니다.

마지막으로 일단 변수가 해석되면 연결된 모든 문자열이 출력됩니다.