PHP의 foreach 루프에서 & for 키 값을 사용하는 문제

WBOY
풀어 주다: 2016-08-04 09:19:49
원래의
1309명이 탐색했습니다.

코드는 다음과 같습니다.

<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 전역 변수의 함정일 것입니다.

관련 라벨:
php
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿