从一道面试题开始
在开始本节内容前,我们先来看看一道还算比较常见的PHP面试题:
1 |
$arr = array('1','2','3'); |
猜一下,运行的结果会是什么呢?熟悉PHP的同学可能已经知道结果了:
2 |
0 => string '1' (length=1) |
3 |
1 => string '2' (length=1) |
4 |
2 => &string '2' (length=1) |
是引用在捣鬼
那么为什么是1,2,2呢。让我们一步步来看:
我们知道对数组执行foreach循环时,是通过移动数组内部指针来实现的。对于上面的例子:当foreach循环结束的时候,由于$v为引用变量,所以$v 与 $arr[ 2 ] 指向了同一个地址空间(共享变量值),之后对$v的任何修改都会直接反映到数组$a中。
要不我们在程序中加入调试代码,看看运行过程的情况吧。
1 |
$arr = array('1','2','3'); |
程序运行的结果是:
02 |
0 => string '1' (length=1) |
03 |
1 => string '2' (length=1) |
04 |
2 => &string '1' (length=1) |
07 |
0 => string '1' (length=1) |
08 |
1 => string '2' (length=1) |
09 |
2 => &string '2' (length=1) |
12 |
0 => string '1' (length=1) |
13 |
1 => string '2' (length=1) |
14 |
2 => &string '2' (length=1) |
简单解释一下:
- 在第一次 foreach 循环里面,$v 是个引用。在循环结束之后,$v 与 $arr[2] = 3,指向了同一个内存块;
- 紧接着第二次循环,$v 引用并没有改变,还是$arr[2]的引用,这时 $v 值是 $arr[0] 的值,所以导致 $arr[2] = 1;
- 同上面,$v 已被 $arr[1] 影响,其值为 2,导致 $arr[2] = 2;
- 所以最终结果是 1, 2, 2.
关于引用,你需要了解的
1. 引用类似于指针,但是不同于指针。
下面的操作让 $a 和 $b 指向了同一个内存块,值为 “str”
试下更改$a和$b中任何一个元素的值。另外一个值都为随之改变:
4 |
$b = "www.nowamagic.net"; |
程序运行结果为:
2. 引用作为函数参数传递时,是可以被函数内部更改的:
05 |
$a = "www.nowamagic.net"; |
程序运行结果为:
3. unset只会删除变量。并不会清空变量值对应的内存空间:
程序运行结果为:
2 |
Notice: Undefined variable: b |
- CentOS磁盘用完的解决办法,以及Tomcat的server.xml里无引用,但是项目仍启动的问题
这是我2018年的第一篇博客...人真是懒了啊...最近在写微信小程序,觉得小程序做的也... 好了不吐槽了,言归正传 前言: 由于我之前不是买了个三年的香港服务器么 , 之前广州2的服务器我就没有续 ...
- foreach里的按引用传值问题
1.foreach($arr as $k=>&$v){ } 这样循环时候最后一个结果前边会有&,出现输出不了的情况,这时候只需要加一个unset($v),加在循环里和外均可. 2 ...
- <c:if>判断两个<c:forEach>里的数据是否相等
问题:两个<c:forEach>嵌套,里面循环的值和外面的值进行比较(里层里的PARENTID是否等于外层的ID),如果相等就显示. <c:forEach items="$ ...
- [PHP] foreach循环的引用赋值可能导致的问题
foreach($arr as &$value)1.引用赋值符号&,是每次循环的时候,把当前元素变成地址,$value变量就是对应元素的地址,循环结束$value是一个指向最后一个元素 ...
- php在foreach中使用引用赋值&可能遇到的问题(转)
楼主在写项目的时候,由于初涉PHP的赋值引用操作,觉得这个功能非常强大,用时一时爽,没有深入了解过其中的原理,导致了一些当时觉得不可思议的BUG,废话不都说,我举个例子详细的描述一下这个问题. 代码: ...
- Python里的引用与拷贝规律
python的可变不可变与各种浅拷贝深拷贝规则,一并梳理. Python一切皆引用 在C++/Java里,int a = 1就是创建变量为a,赋值为1:int b = a就是创建变量b,赋值为a的值. ...
- jsp页面中从forEach里向action里面传递其中的一个对象
<c:forEach var="user" items="${users }"> <form action="user_update ...
- 如何获取c:forEach里面点击时候的值
1.c:forEach遍历输出 <c:forEach items="${data}" var="item" > <a onclick=&quo ...
- 在mvc4里怎样引用:System.Web.Optimization和entityframework
请在nuget 里运行: Install-Package Microsoft.AspNet.Web.Optimizationinstall-package entityframework
随机推荐
- windows core audio apis
这个播放流程有一次当初不是很理解,做个记录,代码中的中文部分,原文档是有解释的:To move a stream of rendering data through the endpoint buff ...
- git extrad_addons 部署说明
注册一个git账号 : 网址: https://github.com/ 1:安装git sudo apt-get install git 2: b把urc扩展占模块pull下来 cd ...
- Library:python-memcached on Windows
1 install memcached 1.4.4 Windows 32-bit 2 cd into the base file and type memcached.exe -d install ...
- [walkthrough] 在Asp.net MVC6 RC里使用NLog,并且把配置集成到config.json
说明一下:本文基于随visual studio 2015 RC公开的DNX1.0.0-beta4,git上最新的aspnet的开发版本已经发生了很大变化. 首先,理论部分看[汤姆大叔的博客] 解读AS ...
- c# 無彈窗调用打印机
using System; using System.Collections.Generic; using System.Text; using System.Configuration; using ...
- 如何将BarTender内容锁定不让改动
条码标签代表的是产品的特性等,具有相当的精确性,所以需要保证它的正确性.而使用BarTender软件,可以帮助小伙伴将设计的条码标签内容锁定,保护它而不被人改动.下面,小编就教教大家如何实现BarTe ...
- [BZOJ 2350] [Poi2011] Party 【Special】
题目链接: BZOJ - 2350 题目分析 因为存在一个 2/3 n 大小的团,所以不在这个团中的点最多 1/3 n 个. 牺牲一些团内的点,每次让一个团内的点与一个不在团内的点抵消删除,最多牺牲 ...
- 24篇Delphi文件操作文章
http://www.cnblogs.com/keyvip/category/268043.html
- zabbix 四张大表分区
trends_uint.ibd history history_unit trends CREATE TABLE `trends` ( `itemid` bigint(20) unsigned NOT ...
- 【HDOJ】2319 Card Trick
水题,STL双端队列. /* 2319 */ #include <iostream> #include <cstdio> #include <cstring> #i ...