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)
}
}
}
당신은 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에 대한 참조는 해당 변수의 상태를 저장할 수있을뿐만 아니라 필요하다는 것을 명심하십시오. 성능에 큰 영향을 미칠 것입니다 -
변수에'&'를 사용하면 변수에 대한 참조가 할당됩니다. http://php.net/manual/pt_BR/language.references.php –
참조가 B :: pushState()가 아닌 A 생성자에서 사용된다는 점에 유의하십시오. – l00k
추한 해결책이 있습니다. 그러나 unserialize (serialize (...)) 그러나 제 생각에는 좀 더 우아한 방법이 있어야합니다. – l00k