zoukankan      html  css  js  c++  java
  • 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	.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)所有,未经作者本人同意禁止任何形式的转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    Azure 云助手主要功能
    静态dll的问题终于搞定了
    青云QingCloud黄允松:最高效的研发管理就是没有管理
    开源libco库:单机千万连接、支撑微信8亿用户的后台框架基石
    青云QingCloud宣布完成C轮融资,金额1亿美元
    NET MVC权限验证
    Fizz-Buzz-Whizz
    API访问客户端
    使用IronPython给.Net程序
    Smart Framework
  • 原文地址:https://www.cnblogs.com/iforever/p/4374083.html
Copyright © 2011-2022 走看看