2017-11-17 1 views
-1

코드는 아래 고려 : 상기 코드같은 객체를 가리키는 두 객체 인스턴스 중 하나가 NULL을 할당 할 때 다르게 동작하는 이유는 무엇입니까?

<?php 
    class SimpleClass { 
    // property declaration 
    public $var = 'a default value'; 

    // method declaration 
    public function displayVar() { 
     echo $this->var; 
    } 
    } 

    $instance = new SimpleClass(); 

    $assigned = $instance; 

    $instance->var = '$assigned will have this value'; 
    var_dump($instance); 
    echo "<br>"; 
    var_dump($assigned); 
?> 

출력은 아래와 같다 :

object(SimpleClass)#1 (1) { ["var"]=> string(30) "$assigned will have this value" } 
object(SimpleClass)#1 (1) { ["var"]=> string(30) "$assigned will have this value" } 

내가 아니라 상기 프로그램을 알. $instance 또는 $assigned에 대한 변경 사항은 동일한 객체 인스턴스를 가리키고 있기 때문에 다른 하나에 반영된다는 사실을 이해했습니다.

그러나이 원칙은 NULL을 두 객체 인스턴스 중 하나에 할당 할 때 아래 코드에서 실패합니다. 두 개체 인스턴스 모두 NULL이되어야하지만 두 인스턴스 중 하나에는 NULL이 포함되고 다른 인스턴스에는 NULL이 포함되지 않아야합니다. 왜 그렇게? 클래스 방법 displayVar() 텍스트 'a default value' 메아리되는 호출되고 있지 아니 위의 코드에서, 또한

NULL 
object(SimpleClass)#1 (1) { ["var"]=> string(15) "a default value" } 

도 존재하는 임의의 생성자 메소드는 다음이있다 : 상기 코드

<?php 
    class SimpleClass { 
    // property declaration 
    public $var = 'a default value'; 

    // method declaration 
    public function displayVar() { 
     echo $this->var; 
    } 
    } 

    $instance = new SimpleClass(); 

    $assigned = $instance; 

    $instance = NULL; 
    var_dump($instance); 
    echo "<br>"; 
    var_dump($assigned); 
?> 

출력은 아래와 같다 어떻게 개체 인스턴스 $assignedvar 속성이 NULL 대신 설정 되나요?

둘 모두의 객체 인스턴스가 동일한 객체를 가리키는 이유는 NULL이 문자열 중 하나에 할당되었거나 그 중 하나에 의미있는 값이 할당 될 때 (예상되는) 다른 방법으로 동작하는 이유는 무엇입니까?

+0

개체를 변수에 할당하면 해당 개체의 전체 개체가 아니라 해당 개체의 '메모리 주소'만 복사됩니다. 내용이있는 객체를 복사하려면 다음을 사용해야합니다 : $ assigned = clone $ instance; – JerzySBG

답변

1

에서보세요 , PHP는 zval을 생성합니다. 객체 구조와 데이터를 보유하는 메모리 공간입니다. Ok, it's somewhat more complex,하지만이 모든 것을 알아야합니다.

$instance에 개체를 지정하면이 zval에 포인터 종류의 것을 할당한다는 것을 의미합니다. 당신이 다음 $assigned = $instance을 수행 할 때, PHP는 너무이 zval에 $assigned 지점을 만드는 :

$instance -> your object <- $assigned 
    ^      ^
    |____________ = ____________| 

그래서 효과적으로 동일한 기본 데이터 구조 (위 -><-로 표시) 두 개의 포인터를 가지고있다.

변수 중 하나에 NULL을 할당하면 해당 변수의 포인터 만 zval에 지워집니다.그러나 다른 변수는 여전히 가리키는 :

$instance = NULL; 

// causes 

$instance -> NULL 
    ^  your object <- $assigned 
    |      ^
    |___________ != ___________| 

이의이 (쉘에서 유형 php -a) 대화 형 세션이를 해보자 :

php > $a = new StdClass; 
php > $a->foo = 42; 
php > $b = $a; 
php > var_dump($b); 
object(stdClass)#1 (1) { 
    ["foo"]=> 
    int(42) 
} 
php > $a = null; 
php > var_dump($b); 
object(stdClass)#1 (1) { 
    ["foo"]=> 
    int(42) 
} 

$assigned 실제로 실제 참조를 사용하는 것과 다릅니다 $instance의 포인터 포인트 : 여기 NULL$instance을 설정

your object <- $instance <- $assigned 
       ^  ^
        |_____= _____| 

, 당신은 개체와 $instance 사이의 연결을 다시 삭제하므로 $assigned도 개체에 대한 (간접적 인) 연결이 끊어집니다.

php > $a = new StdClass; 
php > $a->foo = 42; 
php > $b = &$a; 
php > var_dump($b); 
object(stdClass)#2 (1) { 
    ["foo"]=> 
    int(42) 
} 
php > $a = null; 
php > var_dump($b); 
NULL 
직접 zval 가리 키지 않는 $b = &$a; $b 이렇게함으로써

, 실제로 $a에, 당신은 지정 따라서 때 NULL$a$b 당신에게 $a 반대로, 예를 들어, 할당 어떤 것 당신이 나중에 $b = 42을 할 경우, $a뿐만 아니라 42이 될 것이다 :

$instance = null; 
// causes 
null <- $instance <- $assigned 
      ^  ^
      |_____= _____| 

그래서 심지어 당신은 여전히 ​​$assigned에서 $instance에 대한 참조를 유지하고 $instance = null을 설정할 때. $a$b 사이의 연결을 완전히 삭제/연결 해제하려면 unset을 사용해야합니다.

+0

완전하고 의미있게 설명 된 답변을 보내 주셔서 감사합니다. 마지막 문장에서 "$ b는 $ b를 할당 한 값이됩니다."변수 $ a를 삭제 한 후 변수 $ b에 $ a를 삭제 한 후 빈/비어 있음/NULL이되었으므로 값을 할당 할 수 있음을 의미합니까? (어느 것이 기준 이었습니까?) – user2839497

+0

@ user2839497 죄송합니다. 잘못 입력했습니다. 추가 된 설명. – Gordon

+0

다시 불편을 드려서 죄송합니다. 하지만 이건 내게 마지막 의심이야. "delete $ a"를 사용하여 설정을 해제 ($ a)하거나 $ a = NULL 또는 다른 것을 말하고 있습니까? – user2839497

4

$assigned = $instance은 변수에 새 객체를 할당 할 때마다 기본적으로 객체에 대한 포인터 참조를 만들기 때문에 포인터를 복사한다는 의미입니다. 당신이 $assigned은 아직도 당신이 만든 객체를 가리키는 상태에서 $ 인스턴스 변수에 null을 할당하고 $instance = NULL을 수행 할 때 객체를 생성 할 때

그래서 이전

이 링크 http://php.net/manual/en/language.oop5.references.php

+0

첫 번째 코드 스 니펫을 살펴보십시오. 그것 안에서 속성 값의 변경은 $ assigned와 $ instance 둘 다에 일어나고 있습니다. 따라서 NULL 중 하나에 NULL이 할당되면 동일한 방식으로 동작해야합니다. 왜 그러한 행동의 차이가 다른 유형의 가치에 존재 하는가? – user2839497

+1

@ user2839497 첫 번째 코드 조각에서'$ assigned'와'$ instance' 변수에 의해 참조 된 객체 자체를 변경하고 있습니다. 그러나'$ assigned = NULL'을 할 때 객체가 NULL이되는 것은 아니지만 객체 자체가 여전히 메모리에서 안전 할 때'$ assigned'가 NULL을 참조하게 만듭니다 – Pratansyah

+0

@ user2839497 차이점은 없습니다. 할당 한 변수 모두에서 값을 얻습니다. 하나는'var'이고, 다른 하나는'인스턴스'입니다. –

관련 문제