zoukankan      html  css  js  c++  java
  • PHP二维数组的引用赋值容易犯的错误

    大家一起来分析一下下面这段代码:

    <?php
    
    $arr = array();
    $arr["abc"] = array("sex" => 100, "age" => 18);
    $arr["bcd"] = array("sex" => 200, "age" => 19);
    $arr["cde"] = array("sex" => 250, "age" => 17);
    
    $arr2 = array();
    foreach ($arr as $name => $item) {
        $item2 = &$arr2[$name];
        $item2["sex"] = $item["sex"] + 300;
        $item2["age"] = $item["age"] + 2;
    }
    
    //unset($item2);
    foreach ($arr2 as $name => $item2) {
        echo "name: $name, age: " . $item2['age'] . ", sex: " . $item2['sex'] . PHP_EOL;
    }
    
    echo "too little".PHP_EOL;
    
    //unset($item2);
    $item2 = array("age" => 30, "sex" => 1000);
    print_r($item2);
    
    echo "next step".PHP_EOL;
    
    foreach ($arr2 as $name => $item) {
        echo "name: $name, age: " . $item['age'] . ", sex: " . $item['sex'] . PHP_EOL;
    }

    如果你觉得上面的代码的执行结果是

    name: abc, age: 20, sex: 400
    name: bcd, age: 21, sex: 500
    name: cde, age: 19, sex: 550
    too little
    Array
    (
        [age] => 30
        [sex] => 1000
    )
    next step
    name: abc, age: 20, sex: 400
    name: bcd, age: 21, sex: 500
    name: cde, age: 19, sex: 550

    或者是

    name: abc, age: 20, sex: 400
    name: bcd, age: 21, sex: 500
    name: cde, age: 21, sex: 500
    too little
    Array
    (
        [age] => 30
        [sex] => 1000
    )
    next step
    name: abc, age: 20, sex: 400
    name: bcd, age: 21, sex: 500
    name: cde, age: 21, sex: 500

    那么你就应该继续往下看了。因为上面两个结果都是错误的,真正的执行结果如下:

    name: abc, age: 20, sex: 400
    name: bcd, age: 21, sex: 500
    name: cde, age: 21, sex: 500
    too little
    Array
    (
        [age] => 30
        [sex] => 1000
    )
    next step
    name: abc, age: 20, sex: 400
    name: bcd, age: 21, sex: 500
    name: cde, age: 30, sex: 1000

    为什么会是这样一个结果呢?

    因为在第一个引用赋值的foreach循环结束以后,$item2依然引用着$arr2数组的最后一个元素。而第二个foreach循环的时候,相当于把$arr2数组的元素依次赋值给$item2,也就相当于赋值给最后一个元素。也就是说,在第二个foreach遍历的过程中,$arr2数组的变化是这样的:

    循环到第1个元素时的数组:[1, 2, 1]
    循环到第2个元素时的数组:[1, 2, 2]
    循环到第3个元素时的数组:[1, 2, 2]

    而后的

    $item2 = array("age" => 30, "sex" => 1000);

    是为了告诉大家引用关系依然存在,并且,直接赋值也会导致引用的数据发生变化。(其实,第二个foreach循环时也是使用的直接赋值,只是有点不好观察出来)

    那么,怎样才能将$item2与$arr2的最后一个元素的引用关系去掉呢?其实很简单,只要添加以下语句就可以了。也就是源代码中注释的地方。

    unset($item2);

    这也可以说是PHP的一个小坑,对于PHP新手来说,很容易犯这种错误而云里雾里,不知所措。希望这篇文章能帮到这样的新手。

  • 相关阅读:
    DFS的联通性问题
    Stl-unordered_map 无序关联式容器的基本用法(xmind)
    【图论】匈牙利算法——社会人数规模专家
    AcWing 860. 染色法判定二分图
    AcWing 1227. 分巧克力(二分)
    【图论】【最小生成树】prim【AcWing】局域网&&繁忙的都市
    【图论】拓扑排序
    Stl—bitset用法
    vector< vector<int> > 的初始化
    Floyd——人人都是中间商(50%)
  • 原文地址:https://www.cnblogs.com/alwu007/p/11549829.html
Copyright © 2011-2022 走看看