코드는 다음과 같습니다.
<code>$a = [1, 2, 3]; foreach($a as $key => &$value) { $value = 5; } var_dump($a);</code>
최종 출력 결과는 다음과 같습니다.
<code>array(3) { [0]=> int(5) [1]=> int(5) [2]=> &int(5) }</code>
질문: 마지막 키 값 앞에 주소 문자가 나타나는 이유는 무엇입니까?
코드는 다음과 같습니다.
<code>$a = [1, 2, 3]; foreach($a as $key => &$value) { $value = 5; } var_dump($a);</code>
최종 출력 결과는 다음과 같습니다.
<code>array(3) { [0]=> int(5) [1]=> int(5) [2]=> &int(5) }</code>
질문: 마지막 키 값 앞에 주소 문자가 나타나는 이유는 무엇입니까?
이 var_dump에 &가 나타나는 것은 다른 변수를 사용하여 해당 값을 변경할 수 있음을 의미합니다.
당신처럼
<code class="php">$b = &$a[0]; var_dump($a);</code>
여기서 인쇄하면 첫 번째 키 값에 & 기호가 나타나며 이는 다른 변수($b)를 사용하여 해당 값을 변경할 수 있음을 나타냅니다.
먼저 &
의 기본적인 용법을 알아보겠습니다.
<code class="php">$b = $c = 1; $a = &$b; $a = 2; echo "b=$b,c=$c\n"; $a = &$c; $a = 100; $a = 200; echo "b=$b,c=$c\n"; unset($a); $a = 500; echo "b=$b,c=$c\n";</code>
위의 $b에 대한 참조로 $a를 지정한 후 다시 다른 참조로 지정하거나 unset($a)하지 않는 한 $a를 변경하면 해당 $b의 값이 변경됩니다.
foreach의 경우에도 마찬가지입니다. 루프를 단일 단계로 나누면 다음과 같습니다.
<code class="php">$value = &$a[0]; $value = 5; $value = &$a[1]; $value = 5; $value = &$a[2]; $value = 5;</code>
루프가 끝까지 실행되면 $value는 $a[2]에 대한 참조이므로 다음 형식과 동일합니다.
<code class="php">$a[0] = 5; $a[1] = 5; $value = &$a[2]; $a[2] = 5; var_dump($a);</code>
var_dump가 마지막 키-값 쌍에 & 기호를 인쇄하는 이유를 이해하는 것은 어렵지 않습니다.
일반적인 상황에서는 큰 문제가 발생하지 않지만 foreach의 범위 문제로 인해 루프가 종료된 후에도 $value를 계속 사용할 수 있으므로 몇 가지 놀라운 버그가 나타납니다.
이렇게
<code class="php">$a = [1, 2, 3]; foreach($a as $key => &$value) { $value = $value+5; } var_dump($a); // [6,7,8] foreach($a as $value){} var_dump($a); // [6,7,7]</code>
빈 foreach를 추가하면 $a가 이상해집니다. 그 이유는 빈 foreach의 $value가 상위 &a[2]에 대한 참조이기 때문입니다.
빈 foreach는 다음과 같습니다.
<code class="php">$value = &$a[2]; $value = $a[0]; $value = $a[1]; $value = $a[2];</code>
$value가 $a[2]에 대한 참조이므로 위의 내용을 다음과 같이 다시 작성할 수 있다는 점을 알고 계셨나요?
<code class="php">$a[2] = $a[0]; $a[2] = $a[1]; $a[2] = $a[2];</code>
$a[2]는 빈 foreach에서 지속적으로 변경되며 $a[2]는 $a[1]의 값이 되므로 $a[2] = $a[2] no 영향을 미칩니다. , 값은 여전히 $a[1];
이 놀라운 버그는 $value 변수의 범위로 인해 발생하므로 먼저 이름을 변경하거나 $value 설정을 해제해야 합니다.
<code class="php">$a = [1, 2, 3]; foreach($a as $key => &$value) { $value = $value+5; } var_dump($a); // 要么unset unset($value); // 要么foreach里不要用上面同名的$value,改为$value2222 foreach($a as $value2222){} var_dump($a);</code>
우선 아주아주좋은 질문이라는 점을 말씀드리고 싶습니다. 나는 질문자가 인용문과 인용문이 아닌 것을 구별할 수 없다고 생각합니다.
먼저 두 가지 테스트를 진행했습니다.
<code>$a = [1, 2, 3]; foreach($a as $key => &$value) { $value = 5; } foreach($a as $key => $value) { $value = 6; } var_dump($a);</code>
결과가 어떻게 나올 것 같나요?
<code>array(3) { [0]=> int(5) [1]=> int(5) [2]=> &int(6) }</code>
또 다른 테스트는 다음과 같습니다.
<code>$a = [1, 2, 3]; foreach($a as $key => &$value) { $value = 5; } foreach($a as $key => $value2) { $value2 = 6; } var_dump($a);</code>
이번 출력은 훨씬 더 정상적으로 보입니다.
<code>array(3) { [0]=> int(5) [1]=> int(5) [2]=> &int(5) }</code>
따라서 이 문제는 PHP 전역 변수의 함정일 것입니다.