说一个极有可能在工作中遇到的问题——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)所有,未经作者本人同意禁止任何形式的转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。

最新文章

  1. jQuery 中 jQuery(function(){})与(function(){})(jQuery) 的区别
  2. PHP socket上传文件图片
  3. ReactNative新手学习之路01-创建项目开始
  4. laravel框架总结(七) -- 数据库操作
  5. 【转载】Ubuntu下SVN安装和配置
  6. Hibernate中的继承映射
  7. 关于Android使TextView可以滚动的设置
  8. MongoDB笔记(二)访问权限
  9. android 如何解决模块之间的通讯的耦合问题
  10. IDEA12 KeyGen Download List
  11. 对 Select 的各种操作(JQuery)
  12. Java学习笔记——浅谈数据结构与Java集合框架(第二篇、Queue、Set)
  13. Abp(.NetCore)开发与发布过程2
  14. ES6 学习笔记之二 块作用域与闭包
  15. oracle中增加pga和sga
  16. JDBC基本使用
  17. [MySql]GRANT权限的一些技巧
  18. redis 在 php 中的应用
  19. [转] 插件兼容CommonJS, AMD, CMD 和 原生 JS
  20. 如何使用Apache log4net库与ASP.NET MVC 5日志记录

热门文章

  1. &lt;实训|第九天&gt;掌握linux中普通的权限控制和三种特殊的权限(sst),做合格的运维工程师
  2. java用字符写字符
  3. iOS10-- snapshotViewAfterScreenUpdates 失效
  4. 37-more 简明笔记
  5. MyBatis学习--SqlMapConfig.xml配置文件
  6. Android-动画简介
  7. .net的Hello World之旅
  8. 【BZOJ 3150】新Nim游戏
  9. 【BZOJ 2555】SubString
  10. Cross-Entropy Loss 与Accuracy的数值关系