当前位置:   article > 正文

PHP foreach中的问题_php foreach 释放内存

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

原因
我尽量简洁的介绍一下,但是在这之前需要了解引用的相关知识,网上搜一下或者看下我写的关于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]

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

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

解决方案有两种

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/49664
推荐阅读
相关标签
  

闽ICP备14008679号