从一道面试题开始
在开始本节内容前,我们先来看看一道还算比较常见的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
随机推荐
- MVC埰坑日记 文件权限
public static void DownLoadFile(string FileFullPath) { if (!string.IsNullOrEmpty(FileFullPath) & ...
- Java学习----创建对象的数组
1.初始化数组的长度 2.初始化每个元素对象 3.调用每个对象的方法 public class Student { private String name; public Student() {} p ...
- InvalidArgument=Value of '1' is not valid for 'index'
用ListView实现点击ListView的项删除该项的效果,调用ItemSelectionChanged事件. 代码如下: private void listView1_ItemSelectionC ...
- linux 下面 opcache 拓展
PHP 5.5.0 及后续版本中已经绑定了 OPcache 扩展,只需要在编译安装的时候, 如果你使用--disable-all参数 禁用了默认扩展的构建, 那么必须使用--enable-opcach ...
- Flask-SQLALchemy查询
from: http://blog.sina.com.cn/s/blog_633277f90100kpvm.html 似乎ORM最难设计的部分是查询.特别是面向对象的查询,今天学习SQLAlchemy ...
- linux下svn客户端报错Cannot negotiate authentication mechanism的解决方法
svn客户端报错Cannot negotiate authentication mechanism的解决方法: 问题出现的原因之一: 因为SVN服务器配置了saslauthd服务用来实现与ldap的对 ...
- Zookeeper的设计模式之观察者模式(十)
Watcher是Zookeeper用来实现distribute lock, distribute configure, distribute queue等应用的主要手段.要监控data_tree上的任 ...
- 分布式系统间通信之RPC简单Demo(七)
看似终点,回到起点.第一次接触C#,编写的第一个真正的Demo是基于Socket的简单通信,现在JAVA开始的第一个RPC的Demo也是基于Socket.. 下面通过java原生的序列化,Socket ...
- Netty4.0学习笔记系列之二:Handler的执行顺序(转)
http://blog.csdn.net/u013252773/article/details/21195593 Handler在netty中,无疑占据着非常重要的地位.Handler与Servlet ...
- Boolean类源码分析
Boolean类里面的常量: Boolean.TRUE:这个是调用Boolean的构造函数,新建了一个Boolean对象,所以TRUE是Boolean类型的.用来避免每次都创建新的Boolean对象, ...