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

<?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: , sex:
name: bcd, age: , sex:
name: cde, age: , sex:
too little
Array
(
[age] =>
[sex] =>
)
next step
name: abc, age: , sex:
name: bcd, age: , sex:
name: cde, age: , sex:

或者是

name: abc, age: , sex:
name: bcd, age: , sex:
name: cde, age: , sex:
too little
Array
(
[age] =>
[sex] =>
)
next step
name: abc, age: , sex:
name: bcd, age: , sex:
name: cde, age: , sex:

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

name: abc, age: , sex:
name: bcd, age: , sex:
name: cde, age: , sex:
too little
Array
(
[age] =>
[sex] =>
)
next step
name: abc, age: , sex:
name: bcd, age: , sex:
name: cde, age: , sex:

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

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

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

而后的

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

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

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

unset($item2);

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

PHP二维数组的引用赋值容易犯的错误的更多相关文章

  1. 功能要求:定义一个两行三列的二维数组 names 并赋值,使用二重循环输出二维数组中的元素。

    功能要求:定义一个两行三列的二维数组 names 并赋值,使用二重循环输出二维数组中的元素 names={{"tom","jack","mike&qu ...

  2. C语言中的二维数组

    1.二维数组的定义和引用 一. 数据类型 数组名[常量表达式1][常量表达式2]; (1)假如有个二维数组array[n][m],则行下标的取值范围0~n-1 (2)列下标的取值范围0~m-1 (3) ...

  3. 学JAVA第十天,一维数组及二维数组的使用。

    今天老师讲了JAVA数组,之前学C#的时候就学过一维数组,至于二维数组当时只是粗略普及了一下. 现在想学JAVA又学到了数组,但是这次不同,注重讲二维数组,因为老师知道我们都了解一维数组了. 所以现在 ...

  4. Java编程基础阶段笔记 day06 二维数组

    二维数组 笔记Notes 二维数组 二维数组声明 二维数组静态初始化与二位初始化 二维数组元素赋值与获取 二维数组遍历 二维数组内存解析 打印杨辉三角 Arrays工具类 数组中常见的异常 二维数组 ...

  5. Java二维数组的应用

    package com.imooc; public class ArrayDemo5 { public static void main(String[] args) { //二维数组的声明和创建: ...

  6. java基础-引用数据类型之二维数组(Array)

    java基础-引用数据类型之二维数组(Array) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 之前我们学习过了Java的一维数组,所谓的二维数组就是元素是一堆一维数组的数组,换 ...

  7. 二维数组(解引用、指针数组、数组的指针)——C语言

    二维数组 在说二维数组前先来说下一维数组中的指针数组和和数组的指针 一.一维数组中指针数组和数组指针的区别 指针数组: ]; []的优先级比*高,首先它是一个数组,它的大小是5,它里面存放的数据类型是 ...

  8. 动态二维数组赋值及for循环遍历和toString遍历

    package com.Summer_0421.cn; import java.util.Arrays; /** * @author Summer * 动态二维数组赋值及for循环遍历和toStrin ...

  9. js 二维数组 for 循环重新赋值

    javascript 二维数组的重新 组装 var arr = [[1,2],[3,4],[5,6],[7,8]]; var temp = new Array(); for(var i= 0 ;i&l ...

随机推荐

  1. 命令行中生成 md5、sha1、sha256 校验和

    在测试过程中有时候需要对某个文件Hash值进行校验,如接口返回一个文件下载地址及hash值,那么除了对比平台端展示和接口下发是否一至,还有一个办法就是命令行使用相关命令 1.Window 注:我是在g ...

  2. C++中的平方、开方、绝对值怎么计算

    #include <math.h> //平方 pow() ,);// 4的平方=16 //开方 ,0.5);// 4的平方根=2 );// 4的平方根=2 //整数绝对值 int c = ...

  3. C++标准库分析总结(五)——<Deque、Queue、Stack设计原则>

    本节主要总结标准库Deque的设计方法和特性以及相关迭代器内部特征 1.Deque基本结构 Deque(双向队列)也号称连续空间(其实是给使用者一个善意的谎言,只是为了好用),其实它使用分段拼接起来的 ...

  4. 去掉 webstorm 灰色的数据类型提示

  5. linux下安装apache和php和mysql

    我的系统环境时ubuntu 18.04.3,为了ROS: 首先:安装下面一堆软件包: sudo apt install nginx nginx-doc fcgiwrap sudo apt instal ...

  6. 深入理解WebRTC

    Web Real-Time Communication(Web实时通信,WebRTC)由一组标准.协议和JavaScript API组成,用于实现浏览器之间(端到端)的音频.视频及数据共享. WebR ...

  7. 常用的etl工具比较

    ETL是什么? ETL,是英文 Extract-Transform-Load 的缩写,用来描述将数据从来源端经过抽取(extract).转换(transform).加载(load)至目的端的过程.(数 ...

  8. 微信小程序设置滚动条

    前言 又很久没有写东西了,上周开始将一个APP和一个网站的内容整合到微信小程序中,到这会儿终于搞得快结束了,才发现为啥我的小程序滚动视图没有滚动条,这是闹哪样,没有滚动条的滚动是没有灵魂的. 客官可移 ...

  9. OpenResty之ngx.shared.DICT

    参考链接: resty.core.shdict ngx_shared.DICT 源码正文: dict.lua 部分源码如下: local ffi = require 'ffi' local base ...

  10. C++ vector 比较大小

    写在前: vector 是可以直接 进行比较. vector 默认提供的   operator< 内使用了  std::lexicographical_compare  进行比较, operat ...