$arr=array('a'=>'first','b'=>'second','c'=>'third');
foreach($arr as &$a);
foreach($arr as $a);
print_r($arr);
上面的代码更改了$arr ['c'=>'second']
的最后一个元素。它是如何做到的?
答案 0 :(得分:3)
您正在第一个循环中创建引用。在循环结束时$a
仍然是对数组中最后一个值的引用:
$arr = ['a','b','c'];
foreach($arr as &$a);
debug_zval_dump($arr,$a);
array(3) refcount(2){
[0]=>
string(1) "a" refcount(1)
[1]=>
string(1) "b" refcount(1)
[2]=>
&string(1) "c" refcount(2)
}
因此,为$ a分配内容会改变该值:
//... previous code, and then:
$a = 'I am still a reference';
debug_zval_dump($arr);
array(3) refcount(2){
[0]=>
string(1) "a" refcount(1)
[1]=>
string(1) "b" refcount(1)
[2]=>
&string(22) "I am still a reference" refcount(2)
}
...所以,如果你做第二次foreach,就会发生这种情况:数组中的最后一项将采用第一项的值,因此它的原始值将丢失,并且数组的所有后续项都将丢失。但是,当它设置为自身(最后一个)时,其原始值已经丢失,并且它不会更改任何内容,因此数组的最后一个值将采用最后一个项目的值:
foreach($arr as $a){
debug_zval_dump($arr);
}
array(3) refcount(3){
[0]=>
string(1) "a" refcount(1)
[1]=>
string(1) "b" refcount(1)
[2]=>
&string(1) "a" refcount(2)
}
array(3) refcount(3){
[0]=>
string(1) "a" refcount(1)
[1]=>
string(1) "b" refcount(1)
[2]=>
&string(1) "b" refcount(2)
}
array(3) refcount(3){
[0]=>
string(1) "a" refcount(1)
[1]=>
string(1) "b" refcount(1)
[2]=>
&string(1) "b" refcount(2)
}
简而言之:在循环中使用引用时总是这样做,除非你有非常的理由不:
foreach($array as &$a){
// some logic
}
unset($a); // removes the reference, so you can't accidentally assign something to it and thereby mutate $array itself.