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 ) 说明:查阅相关资料,了解到上述这种语法就可以将所有 ...
随机推荐
- 数据库mark
LOAD DATA INFILE 'I:\QQpwd\\1.txt' IGNORE INTO TABLE sgk.top1 FIELDS TERMINATED BY '----' OPTIONALLY ...
- linux:手动校准系统时间和硬件CMOS时间
windows下OS时间和主板CMOS芯片里的时间通常是一致的,但是linux却不一定,在无法联网自动校准时间的情况下,只能手动调整: 查看系统时间 date 调整系统时间 sudo date -s ...
- Webwork 学习之路【03】核心类 ServletDispatcher 的初始化
1. Webwork 与 Xwork 搭建环境需要的的jar 为:webwork-core-1.0.jar,xwork-1.0.jar,搭建webwork 需要xwork 的jar呢?原因是这样的,W ...
- 求解最大矩形面积 — leetcode 85. Maximal Rectangle
之前切了道求解最大正方形的题,题解猛戳 这里.这道题 Maximal Rectangle 题意与之类似,但是解法完全不一样. 先来看这道题 Largest Rectangle in Histogram ...
- SQL基础之XML
1.XML数据类型 在SQL Server中xml数据类型可以用来保存xml文档,这个文档即可以是完整的xml文档和xml片段,这样开发者就可以像使用int数据类型一样来使用xml数据类型.不过xml ...
- 浅谈JS继承
今天呢,我们来谈谈继承,它也是JS语言中的一大重点,一般什么时候我们会用继承呢,比如有两个拖拽的面板,两个功能基本一致,只是第二个面板多了一些不同的东西,这个时候,我们就会希望,要是第二个直接能继承第 ...
- How to build windows azure PowerShell Source Code
Download any version source code of Windows Azure Powershell from https://github.com/Azure/azure-sdk ...
- jquery的offset与position的区别
这里offset取得是屏幕影藏的y轴的距离➕元素距离屏幕的y轴的距离. 而postion取得的则是,上一个父元素(包含postion定位的)的距离
- javascript位置相关知识点整理
1.css指定元素的位置采用的是文档坐标: 2.js查询元素位置的方法返回的是元素在视口中的位置,即视口坐标: 如何获得元素的位置和尺寸 获得元素的位置和尺寸可以通过getBoundingClient ...
- python2.7到python3代码转换脚本2to3的一些介绍
你的位置: Home ‣ Dive Into Python 3 ‣ 难度等级: ♦♦♦♦♦ 使用2to3将代码移植到Python 3 ❝ Life is pleasant. Death is ...