先看程式碼
$arr = [1, 2, 3];
foreach($arr as &$value){
}
foreach($arr as $value){
}
print_r($arr);
// 預期
Array
(
[0] => 1
[1] => 2
[2] => 3
)
// 實際
Array
(
[0] => 1
[1] => 2
[2] => 2
)
foreach
在執行的時候,會依次把陣列 $arr
鍵的值賦值給 $value
,並且 $value
並不是區域性變數,它存在於全域性中。
所以在第二次 foreach
執行的時候,此時的 $value = &$arr[2]
,由於它的記憶體地址指向了 $arr[2]
,所以在第二次的 foreach
迴圈中,每一次對 $value
的賦值,其實都是在改變 $arr[2]
的值。
$arr = [1, 2, 3];
foreach($arr as &$value){
// 第一次迴圈 $value = &$arr[0];
// 第二次迴圈 $value = &$arr[1];
// 第三次迴圈 $value = &$arr[2];
}
// 迴圈結束後由於 $value 處於全域性中,它依然指向 $arr[2]
// 於是:
foreach($arr as $value){
// 第一次迴圈 $value = $arr[0];
// 實際上 $arr[2] = $arr[0];
// 第二次迴圈 $value = $arr[1];
// 實際上 $arr[2] = $arr[1];
// 第三次迴圈 $value = $arr[2];
// 實際上 $arr[2] = $arr[2];
// 此時 $arr[2] 與 $arr[1] 相等
}
要解決這個問題也很簡單
$arr = [1, 2, 3];
foreach($arr as &$value){
}
// 每次迴圈引用陣列值的時候,迴圈之後要將 $value 釋放掉
unset($value);
foreach($arr as $value){
}
print_r($arr);
// 輸出
Array
(
[0] => 1
[1] => 2
[2] => 3
)
這應該是 PHP新手 經常忽略的問題,要記住 foreach
並不像 function
一樣產生作用域,他的變數處在全域性中。
記錄一下。
本作品採用《CC 協議》,轉載必須註明作者和本文連結