2017-12-29 19 views
0

PHP 7.0PHP 참조가 아닌 직접 지정

배열의 할당과 관련하여 실제로 이상한 동작이 발생합니다. PHP의 배열은 값 copy에 의해 지정되어야합니다 (참조로 직접 설정되지 않은 경우).

로컬 범위에서 한 번 참조되는 변수는 모든 곳에서 참조됩니다 (즉, 내가 추측하는 바입니다). 제 의견으로는 이것이 어떻게 작동해야하는 것이 아닙니다. 한 곳에서는 참조를 만들고 다른 곳에서는 값을 복사하고 싶습니다.

하시기 바랍니다이 예를 살펴 결과가

After B::__construct 
array(1) { 
    ["randoms"]=> 
    array(0) { 
    } 
} 


After A::__construct(B) 
array(1) { 
    ["randoms"]=> 
    &array(0) { 
    } 
} 


After B::doSomething() 
array(1) { 
    ["randoms"]=> 
    &array(1) { 
    [0]=> 
    int(85799664) 
    } 
} 


B::history 
array(3) { 
    [0]=> 
    array(1) { 
    ["randoms"]=> 
    &array(3) { 
     [0]=> 
     int(85799664) 
     [1]=> 
     int(418164754) 
     [2]=> 
     int(1267239969) 
    } 
    } 
    [1]=> 
    array(1) { 
    ["randoms"]=> 
    &array(3) { 
     [0]=> 
     int(85799664) 
     [1]=> 
     int(418164754) 
     [2]=> 
     int(1267239969) 
    } 
    } 
    [2]=> 
    array(1) { 
    ["randoms"]=> 
    &array(3) { 
     [0]=> 
     int(85799664) 
     [1]=> 
     int(418164754) 
     [2]=> 
     int(1267239969) 
    } 
    } 
} 

code fiddle

당신은 B에 대한 참조를 만들어 볼 수 있듯이 :: A가 :: __ 구성 범위는 수에 바르

class A 
{ 

    public $b; 

    public $refVar; 

    public function __construct(B $b) 
    { 
     $this->b = $b; 

     // reference here 
     $this->refVar = &$this->b->vars['randoms']; 
    } 

} 

class B 
{ 

    public $vars = []; 
    public $history = []; 


    public function __construct() 
    { 
     $this->vars['randoms'] = []; 
    } 

    public function doSomething() 
    { 
     // copy value here 
     $this->history[] = $this->vars; 

     $this->vars['randoms'][] = rand(); 
    } 

} 

$b = new B(); 

echo "After B::__construct\n"; 
var_dump($b->vars); 

$a = new A($b); 

echo "\n\nAfter A::__construct(B)\n"; 
var_dump($b->vars); 

$b->doSomething(); 

echo "\n\nAfter B::doSomething()\n"; 
var_dump($b->vars); 

$b->doSomething(); 
$b->doSomething(); 

echo "\n\nB::history\n"; 
var_dump($b->history); 

B :: vars는 모든 곳에서 참조되었습니다.

이 문제를 방지하려면 어떻게해야합니까?

편집 : 오랜 연구 끝에 단순한 예를 들었습니다. 그리고 틀린 것을 발견했습니다 - 그러나 나는이 상황을 방지하는 방법을 모른다.

메타 : 아무도 아직 대답하지 않았으므로 조금 질문을 변경했습니다. 누군가 그것을 이미 따라했기 때문에 나는 그것을 닫고 싶지 않습니다.

편집 2 완전히 만족스럽지 않은 해결책을 게시했습니다. 누군가가이 개념을 어떻게 극복 할 수 있을지 알고 있다면 (어쩌면 개념을 변경하여) 제안을 환영합니다. 하지만 클래스의 B :: vars에 대한 참조는 해당 변수의 상태를 저장할 수있을뿐만 아니라 필요하다는 것을 명심하십시오. 성능에 큰 영향을 미칠 것입니다 -

+0

변수에'&'를 사용하면 변수에 대한 참조가 할당됩니다. http://php.net/manual/pt_BR/language.references.php –

+0

참조가 B :: pushState()가 아닌 A 생성자에서 사용된다는 점에 유의하십시오. – l00k

+0

추한 해결책이 있습니다. 그러나 unserialize (serialize (...)) 그러나 제 생각에는 좀 더 우아한 방법이 있어야합니다. – l00k

답변

0

이 문제는 유일한 해결책은 직렬화 또는로 json_encode를 사용하는 것으로 보인다 bug on php.net

으로 언급 이미하고있다.