PHP中的一個”坑“


說一個極有可能在工作中遇到的問題——foreach的引用

foreach

$arr = range(1,3);
//[1,2,3]

foreach($arr as &$val) {
}

foreach($arr as $val) {
}
print_r($arr);

  上面這段代碼輸出什么呢,神奇的竟然是下面這樣,這個我在工作中遇到過一次,當時弄了半天沒弄出個所以然,只是找到了解決辦法,這個問題解決辦法有兩個:

Array
(
    [0] => 1
    [1] => 2
    [2] => 2
)

  下面這兩種方式都可以解決上面這個問題:

//方法1
foreach ($arr as &$value) {
}
unset($value);
foreach ($arr as $value) {
}
print_r($arr);
//[1,2,3]

//方法2
foreach ($arr as &$value) {
}
foreach ($arr as $val) {
}
print_r($arr);
//[1,2,3]
//方法3
foreach ($arr as &$value) {
}
foreach ($arr as &$value) {
}
print_r($arr);
//[1,2,3]
  

  方法1在官方的手冊中也可以看到http://php.net/manual/en/control-structures.foreach.php,文章中專門有個tips提示這一點   方法2和方法3為什么也ok呢,看了下面就知道了,其實就是引用在”作祟“,foreach中的&$value是一個指向數組中某一個元素的指針變量,先看下面個,這個很好理解,tmp是var的引用,指向的是var的存儲空間,當tmp改變的時候,var也改變

$var = 123;
$tmp = &$var;
$tmp = 200;
echo $var;
//200

   看看下面這張盜來的圖(哈哈,原文鏈接貼在下面),對上面這個更好的理解      好了,這個ok了之后再看下面的(我不知道上面這種圖用什么軟件畫的,只能手繪了,囧~~),先看第一個foreach:

第二次foreach:   這個時候就很容易知道其實第二次foreach循環,數組中最后一個元素值真是多變啊~~,從第一個元素一直變到倒數第二個,要解決這個問題,很簡單,切斷$value與第二次foreach的關系,因此,unset可以,換個變量名也可以,或者將指針重置也可以(方法3),好了,至此,這個問題到這個地方基本可以理解個所以然了。

  好,再看看下面這個官方文檔下面的評論,應該可以很容易理解了

<?php
$arr1 = array("a" => 1, "b" => 2, "c" => 3);
$arr2 = array("x" => 4, "y" => 5, "z" => 6);

foreach ($arr1 as $key => &$val) {}
foreach ($arr2 as $key => $val) {}

var_dump($arr1);
var_dump($arr2);
?>
#The output is:

array(3) { ["a"]=> int(1) ["b"]=> int(2) ["c"]=> &int(6) }
array(3) { ["x"]=> int(4) ["y"]=> int(5) ["z"]=> int(6) }

calluserfunc_array ####

通過calluserfunc_array調用函數的時候有引用參數的話還要用引用(PHP5.4開始),看看下面官方的說明 看下面這個例子:

<?php
function test(&$a, &$b)
{
    $a = "YRT";
    $b = "TEST";
}
$c=0;
$d=0;

#下面的內容會發出warning
#Warning: Parameter 1 to test() expected to be a reference, value given in D:\iforever\t.php on line 9
#我的環境是PHP5.5.1
call_user_func_array("test", array($c, $d));
var_dump($c);
var_dump($d);

#下面的輸出
#string(3) "YRT"
#string(4) "TEST"
call_user_func_array("test", array(&$c, &$d));
var_dump($c);
var_dump($d);

參考文章:

  http://www.cnblogs.com/CraryPrimitiveMan/p/4030748.html#3085766

 http://www.jb51.net/article/39299.htm

  本文版權歸作者iforever(luluyrt@163.com)所有,未經作者本人同意禁止任何形式的轉載,轉載文章之后必須在文章頁面明顯位置給出作者和原文連接,否則保留追究法律責任的權利。


免責聲明!

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



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