鍍金池/ 問答/PHP  網(wǎng)絡安全/ PHP foreach()里使用& 引用賦值

PHP foreach()里使用& 引用賦值

<?php
$data = ['a','b','c'];

foreach ($data as &$v) {

}

foreach ($data as $v) {

}

unset($v);

var_dump($data);

這段代碼的結(jié)果如何推導?是什么原理?

回答
編輯回答
六扇門

好像以前見過類似的問題...

<?php
/* 第一次遍歷 */
$v = &$data[0];
$v = &$data[1];
$v = &$data[2];

// 第一次遍歷完成后, 這個時候 $v = &$data[2]


/* 第二輪遍歷 */
// 因為$v等價于$data[2],相當于$data[2] = $data[0],把$data[2]賦值為a(即$data[0]); 此時數(shù)組array = ['a','b','a'];
$v = $data[0]; 

// 因為$v等價于$data[2],相當于$data[2] = $data[1],把$data[2]賦值為b(即$data[1]); 此時數(shù)組array = ['a','b','b'];
$v = $data[1]; 

// 因為$v等價于$data[2],相當于$data[2] = $data[2],即賦值為其本身,而此時已經(jīng)被上一次賦值為b; 此時數(shù)組array = ['a','b','b'];
$v = $data[2]; 

// 第二次遍歷完后, array = ['a','b','b']

unset($v); // unset($v)釋放掉臨時的引用

var_dump($data);

最后輸出:

array(3) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [2]=>
  string(1) "b"
}
2018年6月6日 06:15
編輯回答
拽很帥

這個經(jīng)典問題鳥哥早就說明過了,這里的一個點需要注意的是,第一次循環(huán)結(jié)束,$v是$data[2]的引用就可以了。
上面的答案講的都很好了,我這里只能來一份補充資料,從php源碼角度解析的php引用,給你網(wǎng)址吧:https://www.cnblogs.com/ohmyg...

2017年10月6日 05:48
編輯回答
尐潴豬

這個問題好老啊,不過上面的大神解釋的很詳細。我對傳引用的理解就是引用和賦值的變量共用了一塊地址空間

2018年8月18日 19:36
編輯回答
傻叼

首先要明白foreach是一個不斷賦值的過程

第一輪循環(huán)實際是數(shù)組元素地址值的賦值,這并不會改變數(shù)組元素??聪旅孢@個簡單實例:

$t = array();
$t[0] = 3;
$t[1] = 4;
$a = &$t[0];
$a = &$t[1];
echo $t[0]; // 數(shù)組第一個元素并沒有被改成4

開始第二輪循環(huán)之前,并沒有銷毀$v這個指針變量,它其實是指向數(shù)組最后一個元素的。
循環(huán)第一次,$v='a',實際是將數(shù)組最后一個元素更改成'a',這個時候打印數(shù)組就是'a','b','a'
循環(huán)第二次,$v='b',實際是將數(shù)組最后一個元素更改成'b',這個時候打印數(shù)組就是'a','b','b'
循環(huán)第二次,$v='b',實際是將數(shù)組最后一個元素更改成'b',這個時候打印數(shù)組就是'a','b','b'
所以這就是數(shù)組最后的值。

2017年12月14日 14:17