PHP中的一个”坑“
说一个极有可能在工作中遇到的问题——foreach的引用
foreach
$arr = range(1,3);
//[1,2,3]
foreach($arr as &$val) {
}
foreach($arr as $val) {
}
print_r($arr);
上面这段代码输出什么呢,神奇的竟然是下面这样,这个我在工作中遇到过一次,当时弄了半天没弄出个所以然,只是找到了解决办法,这个问题解决办法有两个:
Array
(
[0] => 1
[1] => 2
[2] => 2
)
下面这两种方式都可以解决上面这个问题:
//方法1
foreach ($arr as &$value) {
}
unset($value);
foreach ($arr as $value) {
}
print_r($arr);
//[1,2,3]
//方法2
foreach ($arr as &$value) {
}
foreach ($arr as $val) {
}
print_r($arr);
//[1,2,3]
//方法3
foreach ($arr as &$value) {
}
foreach ($arr as &$value) {
}
print_r($arr);
//[1,2,3]
方法1在官方的手册中也可以看到http://php.net/manual/en/control-structures.foreach.php,文章中专门有个tips提示这一点
方法2和方法3为什么也ok呢,看了下面就知道了,其实就是引用在”作祟“,foreach中的&$value是一个指向数组中某一个元素的指针变量,先看下面个,这个很好理解,tmp是var的引用,指向的是var的存储空间,当tmp改变的时候,var也改变
$var = 123;
$tmp = &$var;
$tmp = 200;
echo $var;
//200
看看下面这张盗来的图(哈哈,原文链接贴在下面),对上面这个更好的理解
好了,这个ok了之后再看下面的(我不知道上面这种图用什么软件画的,只能手绘了,囧~~),先看第一个foreach: 
第二次foreach:
这个时候就很容易知道其实第二次foreach循环,数组中最后一个元素值真是多变啊~~,从第一个元素一直变到倒数第二个,要解决这个问题,很简单,切断$value与第二次foreach的关系,因此,unset可以,换个变量名也可以,或者将指针重置也可以(方法3),好了,至此,这个问题到这个地方基本可以理解个所以然了。
好,再看看下面这个官方文档下面的评论,应该可以很容易理解了
<?php
$arr1 = array("a" => 1, "b" => 2, "c" => 3);
$arr2 = array("x" => 4, "y" => 5, "z" => 6);
foreach ($arr1 as $key => &$val) {}
foreach ($arr2 as $key => $val) {}
var_dump($arr1);
var_dump($arr2);
?>
#The output is:
array(3) { ["a"]=> int(1) ["b"]=> int(2) ["c"]=> &int(6) }
array(3) { ["x"]=> int(4) ["y"]=> int(5) ["z"]=> int(6) }
calluserfunc_array ####
通过calluserfunc_array调用函数的时候有引用参数的话还要用引用(PHP5.4开始),看看下面官方的说明
看下面这个例子:
<?php
function test(&$a, &$b)
{
$a = "YRT";
$b = "TEST";
}
$c=0;
$d=0;
#下面的内容会发出warning
#Warning: Parameter 1 to test() expected to be a reference, value given in D:\iforever\t.php on line 9
#我的环境是PHP5.5.1
call_user_func_array("test", array($c, $d));
var_dump($c);
var_dump($d);
#下面的输出
#string(3) "YRT"
#string(4) "TEST"
call_user_func_array("test", array(&$c, &$d));
var_dump($c);
var_dump($d);
参考文章:
http://www.cnblogs.com/CraryPrimitiveMan/p/4030748.html#3085766
http://www.jb51.net/article/39299.htm
本文版权归作者iforever(luluyrt@163.com)所有,未经作者本人同意禁止任何形式的转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
PHP中的一个”坑“的更多相关文章
- andriod8.1.0源码编译中的一个坑-package com.sun.javadoc does not exist
这里记录编译过程中的一个坑!!! 编译过程中出现了下面的报错 external/doclava/src/com/google/doclava/ClassInfo.java:20: error: pac ...
- 记前端状态管理库Akita中的一个坑
记状态管理库Akita中的一个坑 Akita是什么 Akita是一种基于RxJS的状态管理模式,它采用Flux中的多个数据存储和Redux中的不可变更新的思想,以及流数据的概念,来创建可观察的数据存储 ...
- Spring Boot 计划任务中的一个“坑”
计划任务功能在应用程序及其常见,使用Spring Boot的@Scheduled 注解可以很方便的定义一个计划任务.然而在实际开发过程当中还应该注意它的计划任务默认是放在容量为1个线程的线程池中执行, ...
- xcode中得一个坑
因项目需求变动,我必须在coredata中的WorkLogModel表中添加一个字段:抄送人.起初我给这个字段起名为copyPerson,一切准备就绪后,发现从数据库读取这个copyPerson时,第 ...
- HashMap 中的一个“坑”!
最近公司新来了一个小伙伴,问了磊哥一个比较"奇怪"的问题,这个问题本身的难度并不大,但比较"隐蔽",那究竟是什么问题呢?接下来我们一起来看. 起因 最近公司 ...
- 关于abp中使用的sweetalert对话框组件的confirm确认对话框中的一个坑
今天修改了一个功能,限制删除用户,在删除的时候不满足条件的时候提示用户原因,使用的sweet alert组件. abp框架前端集成了sweet alert 对http请求的error做了全局处理,我在 ...
- 在Java中==的一个坑
观察下面代码,输出结果是什么? public static void main(String[] args) { Integer p = 10000; Integer q = 10000; Syste ...
- mysql 线上not in查询中的一个坑
今天早上开发又过来说,怎么有个语句一直没有查询出结果,数据是有的呀,并发来了如下的sql(为了方法说明,表名及查询均做了修改): select * from t2 where t2.course no ...
- Makefile中的一个坑
问题描述:Makefile中,我想将一个变量的后缀全部进行替换,如将所有的.c后缀变成.d后缀 方法:$(CUR_SOURCE: .c = .d ) 说明:查阅相关资料,了解到上述这种语法就可以将所有 ...
随机推荐
- TinyFrame再续篇:整合Spring AOP实现日志拦截
上一篇中主要讲解了如何使用Spring IOC实现依赖注入的.但是操作的时候,有个很明显的问题没有解决,就是日志记录问题.如果手动添加,上百个上千个操作,每个操作都要写一遍WriteLog方法,工作量 ...
- WPF 绑定枚举值
前台Xaml <ComboBox x:Name=" HorizontalAlignment="Left" Margin="5 0 0 0" Se ...
- 内网穿透神器ngrok——将本地项目驾到外网
相信做Web开发的同学们,经常会遇到需要将本地部署的Web应用能够让公网环境直接访问到的情况,例如微信应用调试.支付宝接口调试等.这个时候,一个叫ngrok的神器可能会帮到你,它提供了一个能够在公网安 ...
- Android开发之AutoCompleteTextView的简单使用
这里只谈简单的使用: 代码xml: <AutoCompleteTextView android:id="@+id/actv" android:layout_width=&qu ...
- java中的重绘
void java.awt.Container.validate()Validates this container and all of its subcomponents.这个函数更新容器及其全部 ...
- python代码缩进
习惯了java,c++之类的宽容,初学python,被它摆了道下马威,写if else,竟然必须要我正确用缩进格式,原来在python里不能用括号来表示语句块,也不能用开始/结束标志符来表示,而是靠缩 ...
- 第七章 java基础类库
1. 日期时间: 用Calendar类. 2. 分隔符:空格.tab.回车. 3. Scanner:读取键盘输入.读取文件. 4. 系统类: System Runtime. 5. 所有的java类都 ...
- [转]Cookie/Session机制详解
原文地址:http://blog.csdn.net/fangaoxin/article/details/6952954 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用 ...
- 单例模式(Singleton Pattern)
意图 保证一个类仅有一个实例,并提供一个该实例的全局访问点 可将一个实例扩展到n个实例.限定某类最多只能创建n个实例. 双重锁定实现单例模式 C# public sealed class Single ...
- word2007插入页码里面不显示或没选项可点怎么办?
1.打开Word 2007 2.单击Microsoft Office按钮 (左上角的圆圈) 3.单击“Word 选项”(在页面的右下方) 4.单击“加载”项(页面左边一排,倒数第三个,出现的页面中,向 ...