說說PHP中foreach引用的一個坑


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/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM