foreach 中使用引用的问题

php 通过循环修改一个数组是常用的操作,可以通过这种方法实现:

foreach($arr as $k=>$v){

   $arr[$k]=$v*2;

}

这种方式直接操作数据很简洁,也不容易带来其它负作用,但很多时候我们并没有用到$k,于是就会跳过$k,直接使用“引用”:

foreach($arr as &$v){

  $v=$v*2;

}

一般情况下,我们这样使用并不会带来什么问题,但有这么两种情况会出现意想不到的结果,尽管现实的业务代码中不太可能出现,但了解一下总是好的:

情况一:

$arr=array(1,2,3);
foreach($arr as &$v){

}
foreach($arr as $v){

}
var_dump($arr);

//结果:array(3) { [0]=> int(1) [1]=> int(2) [2]=> &int(2) }

这种情况的结果

如果多试几个数组的话,你会发现:数组的最后一个元素被修改为倒数第二个元素了。

 

发生的条件

1. 在同一个作用域下同一个数组循环了2次(循环多次也会出现类似的结果);

2. 第一个循环中的$v使用了引用,第二个没有使用引用

如果这两个条件不能同时满足,就不会出现这种“异常”。

 

为什么会出现这种情况呢?

原因有两点:

1. 每次foreach循环的过程,实际上有个隐形的操作:

foreach($arr as $k=>$v){

  $v=$arr[$k]; //内部实际有这一步的操作,即使你没有写$k,内部也有个临时变量,作用同$k

}

2. 当$v使用引用的时候,循环完成后$v保留了对数据最后一个元素,$arr[$k] 的引用。

即第一次循环后,$v=$arr[2];

第二次循环的时候:

 foreach($arr as $v){
   //$k=0时: 
     $v=$arr[0];//因为$v是$arr[2]的引用,所以这一步相当于:$arr[2]=$arr[0];
  //$k=1 时:
     $arr[2]=$arr[1];
  //$k=2 时:
     $arr[2]=$arr[2];//而$arr[2],在当$k=1时赋值为什么$arr[1],所以最后$arr[2]=$arr[1]
 }

 

 

情况二:

$arr=array(1,2,3);
foreach($arr as $k=>$v){
    $v=&$arr[$k];
}
var_dump($arr);
//结果:array(3) { [0]=> int(2) [1]=> int(3) [2]=> &int(3) }

这种情况的结果是:

数组的每个元素左移一位,最后一位不变。

 

为什么会这样呢?

如果了解前一种情况的话,这种情况理解起来就比较容易了:

$arr=array(1,2,3);
foreach($arr as $k=>$v){
    $v=&$arr[$k];
    /* 
     当 $k=0 时:
      $v=&$arr[0];
     当 $k=1 时:
      $v=&$arr[1];而$v而是$arr[0]的引用,即:$arr[0]=&$arr[1];
     当 $k=2 时:
      $v=&$arr[2];即:$arr[1]= &$arr[2];因为每一次赋值的操作对象都是前一个元素,所以最后一个元素并没有被左移
    */
}

 

 

转载于:https://my.oschina.net/agui1989/blog/1606082

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值