From: http://blog.csdn.net/yipiankongbai/article/details/45307767
先來看看下面這段代碼:
<?php $arr = array('apple','banana','cat','dog'); foreach($arr as $key=>$val) { //some code } echo $val; //輸出dog echo $key; //輸出3 //下面對val進行賦值 $val = 'e'; print_r($arr); //輸出Array ( [0] => apple [1] => banana [2] => cat [3] => dog )
說明:在上面的foreach循環中,當循環結束后,$key和$val變量都不會被自動釋放掉。值會被保存下來。而且此時修改$val的值不會影響$arr。
引用:如果想在遍歷數組的過程中修改數組的元素,可以在foreach中對$val使用引用。此時被引用的元素$val指向當前數組元素的內存地址,即共享一段內存地址。因此修改$val的值會同時改變$arr[$key]的值。
再來看看下面一段在foreach中使用引用的代碼,這是最近在項目中遇到的一種情況:
<?php $arr = array('apple','banana','cat','dog'); //在foreach中使用引用 foreach($arr as $key => &$val) { $val = 'new value'; } echo $val; //輸出new value echo $key; //輸出3 $val = 'egg'; print_r($arr); //輸出Array ( [0] => new value [1] => new value [2] => new value [3] => egg )
說明:在foreach中使用&引用后,當foreach結束后,$key和$val變量也都不會被自動釋放掉,但是此時$val和$arrcount($arr) - 1指向相同的內存地址。因此,此時修改$val的值也會改變了$arr[3]的值。
這種情況下很容易犯的錯誤就是像上面例子所示,在循環外面繼續使用被foreach引用的變量,這樣會使開發者得不到預期的數據。因此,為了避免這種情況的發生,應該在適當的位置釋放變量的引用。以上面的代碼為例:
<?php
$arr = array('apple','banana','cat','dog');
//在foreach中使用引用
foreach($arr as $key => &$val)
{
$val = 'new value';
}
unset($val);
echo $val; //報錯,Notice: Undefined variable: val
echo $key; //輸出3
$val = 'egg';
print_r($arr); //輸出Array ( [0] => new value [1] => new value [2] => new value [3] => new value ) 在foreach結束后unset $val,此時會釋放對$val的引用。因此改變$val不會對$arr造成影響。
這是最近在項目中遇到的坑和解決方案的總結,如果錯誤或更好地建議,歡迎指出。
原文地址:http://www.aintnot.com/2015/04/25/talk-about-a-hole-in-php-foreach-quote/