·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> php网站开发 >> PHP中的一个”坑“

PHP中的一个”坑“

作者:佚名      php网站开发编辑:admin      更新时间:2022-07-23
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)

  下面这两种方式都可以解决上面这个问题:

//方法1foreach ($arr as &$value) {}unset($value);foreach ($arr as $value) {}print_r($arr);//[1,2,3]//方法2foreach ($arr as &$value) {}foreach ($arr as $val) {}print_r($arr);//[1,2,3]//方法3foreach ($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开始),看看下面官方的说明 看下面这个例子:

<?phpfunction 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.1call_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([email protected])所有,未经作者本人同意禁止任何形式的转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。