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: , 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二维数组的引用赋值容易犯的错误的更多相关文章
- 功能要求:定义一个两行三列的二维数组 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 ...
随机推荐
- 持续api管理翻译
- 书籍内容 > 地址: https://www.safaribooksonline.com/library/view/continuous-api-management/97814920435 ...
- [CSP-S模拟测试]:跳房子(模拟)
题目描述 跳房子,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一.跳房子是在$N$个格子上进行的,$CYJ$对游戏进行了改进,该成了跳棋盘,改进后的游戏是在一个$N$行$M$列的棋盘上进行,并 ...
- Factor_Analysis
Factor_Analysis(因子分析) Factor Analysis 简书:较好理解的解释,其中公式有一定的推导(仅展现关键步骤,细节大多需要自行补充),基本为结论式. 感性层面理解:首先,明确 ...
- 图片上传利用request.getInputStream()获取文件流时遇到的问题
图片上传功能是我们web里面经常用到的,获得的方式也有很多种,这里我用的是request.getInputStream()获取文件流的方式.想要获取文件流有两种方式,附上代码 int length = ...
- OpenJudge计算概论-大象喝水
/*========================================================= 大象喝水 总时间限制: 1000ms 内存限制: 65536kB 描述 一只大象 ...
- 知乎千万级高性能长连接网关 https://zhuanlan.zhihu.com/p/66807833
知乎千万级高性能长连接网关揭秘 9 天前 · 来自专栏 知乎技术专栏 实时的响应总是让人兴奋的,就如你在微信里看到对方正在输入,如你在王者峡谷里一呼百应,如你们在直播弹幕里不约而同的 666,它们的背 ...
- c++ 套接字 --->2002 java NIO --->netty
c++ 套接字 --->2002 java NIO --->netty
- iOS12 中的后台下载与上传
严格意义上来说,iOS并不能像Android一样,真的在后台开启一个下载Service,一直下载.但是它可以进行在系统允许范围内的后台上传和下载. 当使用 NSURLSessionConfigurat ...
- uefi是如何启动linux内核的?
答:uefi启动linux内核有两条路径: 1. uefi直接进入uefi shell来启动linux内核 2. uefi直接进入uefi shell启动grub启动器,然后进入grub shell启 ...
- angular自定义组件
https://cli.angular.io/ 打开终端创建header组件: ng g component components/header import { Component, OnInit ...