php二维数组引用变量,PHP二维数组的引用赋值容易犯的错误

本文详细分析了一段PHP代码,解释了在处理二维数组时引用赋值可能导致的意外结果。在代码中,由于引用的关系,第二次foreach循环实际上修改了数组的同一元素。解决这个问题的方法是在循环结束后使用`unset()`解除引用。文章还介绍了如何使用二重循环输出二维数组的内容,并提醒初学者注意此类常见错误。
摘要由CSDN通过智能技术生成

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

$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新手来说,很容易犯这种错误而云里雾里,不知所措。希望这篇文章能帮到这样的新手。

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

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

C语言中的二维数组

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

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

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

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

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

Java二维数组的应用

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

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

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

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

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

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

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

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

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

随机推荐

python随便笔记。。。

一.input().strip(),strip()的作用是不读取用户输入的空格 s.strip(rm)        删除s字符串中开头.结尾处,位于 rm删除序列的字符s.lstrip(rm)    ...

eclipse开发环境搭建

1.eclipse插件OpenExplorer快速打开文件目录 下载地址:https://github.com/samsonw/OpenExplorer/downloads 下载jar包,将jar包放 ...

jqueryui引用出错(base is not a constructor,widget no found)

出错的原因,主要是引用顺序出错. 正确顺序如下: query本身必须放在第一位:

在上一篇项目 管理实践教程二.源代码控制[Source Control Using VisualSVN Server and TortoiseSVN]中 我们已经讲解了如何使用TortoiseSVN和 ...

php 实现简单购物车

今天在练习购物车以及提交订单,写的有点头晕,顺便也整理一下,这个购物车相对来说比较简单,用于短暂存储,并没有存储到数据库, 购物车对于爱网购的人来说简直是熟悉的不能再熟悉了,在写购物车之前,我们首先要 ...

新建的小程序没有app.js,app.json等文件

因为在创建的时候没有勾选 建立普通快速启动模板,而我在创建的时候没有发现有这个选项可以选择. 解决办法:把之前创建过的文件夹整个删掉,不能只删内容.然后再重新新建项目,就会出现  建立普通快速启动模板 ...

C#中异步使用及回调

1. 一句话理解异步 我叫你去吃饭,叫完你不去,那我就会一直等你,直到你和我一起去吃饭.这叫同步! 我叫你去吃饭,叫完不管你去不去,我都不会等你,我自己去吃饭.这叫异步! 2. 异步使用 static ...

python 获取IP

第一种 import commandscmd = "ifconfig br0 | grep 'inet addr' | sed 's/^.*addr://g' |sed 's/ Bcast: ...

【模板 && 拓扑】 Dijkstra 单源最短路径算法

话不多说上代码 链式前向星233 #include using namespace std; ,_max=0x3fffffff; //链式前向星 struct ...

cmake 强制链接静态库

add_executable(main main.cpp) target_link_libraries(main ${CMAKE_SOURCE_DIR}/libbingitup.a) 静态库和动态库共 ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值