PHP foreach中的问题

使用foreach总结下面几个问题,欢迎补充

foreach不支持顺序输出数组

代码如下

$commonArray = [1, 2, 3, 4, 5];
$shuffleArray = [];
$shuffleArray[1] = 1;
$shuffleArray[2] = 0;
$shuffleArray[0] = 9;
$shuffleArray[3] = 2;
$shuffleArray[4] = 5;
foreach($commonArray as $item) {
    print_r($item);
}
//12345

foreach($shuffleArray as $item) {
    print_r($item);
}
// 10925
foreach引用问题

问题
我们对第一个数组引用循环完了以后,第二个数组正常循环发现最后一个值有问题,代码如下

$array = [1, 2, 3, 4, 5, 6];
foreach ($array as &$element) {}
echo implode(',', $array); // 1,2,3,4,5,6
echo "<hr>";
foreach($array as $element) {}
echo implode(',', $array); // 1,2,3,4,5,5

原因
我尽量简洁的介绍一下,但是在这之前需要了解引用的相关知识,网上搜一下或者看下我写的关于PHP引用的文章

传送门 PHP 值拷贝和引用拷贝

代码示例

$array = [1, 2, 3, 4, 5, 6];

foreach ($array as &$element) {
}
// 对数组引用进行循环可以理解为执行了以下操作
$element = &$array[0];
$element = &$array[1];
$element = &$array[2];
$element = &$array[3];
$element = &$array[4];
$element = &$array[5];
// 循环结束以后element没有释放的话,保持了对数组第五个元素的引用

// 这时候我们修改element的值的话,相当于是对arr[5]进行了赋值操作,看下面
print_r($array); // [1, 2, 3, 4, 5, 6]
$element = 988; 
print_r($array); // [1, 2, 3, 4, 5, 988]
$element = 333;
print_r($array); // [1, 2, 3, 4, 5, 333]
// 上面代码没有问题的话,这个代码块就结束了,现在element是建立了对数组arr[5]的一个引用

// 看下第二个循环,这次我们没有进行引用赋值,这就是一个普通的遍历
foreach($array as $element){
	 print_r(implode(',', $array));
     echo "<br>";
}  
// 上面循环会出现
//1,2,3,4,5,1
//1,2,3,4,5,2
//1,2,3,4,5,3
//1,2,3,4,5,4
//1,2,3,4,5,5
//1,2,3,4,5,5

// 循环内发生了什么呢
// 其实是这样的
// 上面我们已经知道 element = &array[5],修改element会修改array[5]的值
// 那么普通循环每次就是一个赋值操作呀,对吧,其实是进行了下面的操作,伪代码哈:
// > 行是执行过程,下面一行是数组被改变后的值
// loop 1 > element = array[5] = array[0] = 1 
// 			$array = [1, 2, 3, 4, 5, 1]
// loop 2 > element = array[5] = array[1] = 2 
// 		    $array = [1, 2, 3, 4, 5, 2]
// loop 3 > element = array[5] = array[2] = 3
//			$array = [1, 2, 3, 4, 5, 3]
// loop 4 > element = array[5] = array[3] = 4 
//			$array = [1, 2, 3, 4, 5, 4]
// loop 5 > element = array[5] = array[4] = 5
//  		$array = [1, 2, 3, 4, 5, 5]
// loop 6 > element = array[5] = array[5] = 5
//			$array = [1, 2, 3, 4, 5, 5]

// 如果坚持看到这儿,可能一下子又蒙了,为什么会出现[1,2,3,4,5,5]
// 到了loop 5 ,我们发现 array已经变成了[1, 2, 3, 4, 5, 5], 
// 到了loop 6 ,loop 6 需要loop 5 array的第六个元素,也就是array[5]的值
// loop 5 array[5] = 5
// 所以数组遍历结果是 [1,2,3,4,5,5]

如果还是不明白,细细品一下,以前面试碰到这种题目总感觉挺刁钻的,但是其实考察的就是对PHP引用的理解

解决方案有两种

  • 使用unset()及时释放掉自己不需要的变量
foreach($array as &$item) {}
unset($item); // 最重要的一步
foreach($array as $item) {}
print_r($item);
  • array_walk替代,array_walk会产生闭包,闭包内变量作用域只限定于闭包内,所以不需要unset变量,可以尽情写你的逻辑,缺点就是,如果有的业务逻辑需要 continue, break的话,不太好处理,那就推荐第一种方式
array_walk($array, function (&$element) {});
array_walk($array, function (&$element) {});
print_r($array);

各有优劣,视实际情况使用吧

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值