關(guān)于 PHP 引用的一個問題引發(fā)的思考

問題一

我們先來看一段代碼:

$a=[1,2,3];   

foreach($a as &$v){

} 

foreach($a as $v){

}
var_dump($a);

我們來看一下運行結(jié)果是什么

array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  &int(2)
}

是不是和大家想的不一樣。

我們注意到運行結(jié)果里面,數(shù)組的最后一個元素是帶有引用,這就是出現(xiàn)這樣結(jié)果的關(guān)鍵所在。

讓我們來分析一下運行過程,當(dāng)程序運行完第一個循環(huán)之后,由于循環(huán)的變量$v是引用類型,而在循環(huán)結(jié)束之后,變量 $v 會被保留下來,并且作為引用類型指向數(shù)組 $a 的最后一個元素。這樣在執(zhí)行第二個循環(huán)的時候,會將 $a[0]、$a[1]的值依次賦值給 $v, 也即 $a[2]。所以在最后一次循環(huán)之前,$a[2] 的值變成了 2。而最后一次循環(huán)的時候,并不會改變 $a[2]的值,這樣就得到了上面的結(jié)果。

總結(jié)
造成以上結(jié)果的主要原因是,如果循環(huán)使用的變量是引用類型的話,循環(huán)結(jié)束,這個變量會作為引用變量被保留下來,并且指向循環(huán)變量的最后一個元素。所以在循環(huán)外修改這個變量的話,會影響循環(huán)變量最后一個元素的值。
因此在寫代碼的時候,如果循環(huán)使用的變量是引用類型的話,在循環(huán)結(jié)束可以對變量進行 unset 操作,這樣就不會有這樣的問題了。

問題二

讓我們再來看一段代碼

$a=[1,2,3];
foreach($a as $v){
    $a[2] = 0;
    var_dump($a);
    var_dump($v);
}

讓我們來看一下運行結(jié)果

array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(0)
}
int(1)
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(0)
}
int(2)
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(0)
}
int(3)

然我們稍微改一下代碼

$b = &$a[2];
foreach($a as $v){
    $b = 0;
    var_dump($a);
    var_dump($v);
}

運行結(jié)果如下

array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  &int(0)
}
int(1)
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  &int(0)
}
int(2)
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  &int(0)
}
int(0)

看出來不同了么?

對于第一段代碼 Demo,在數(shù)組循環(huán)開始之后,在循環(huán)中修改數(shù)組的值不會影響循環(huán);而如果有引用變量指向數(shù)組的元素,在循環(huán)中修改引用變量的值則會影響循環(huán)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容