php foreach

foreach有2种遍历方式
1.值遍历
2.引用遍历

值遍历

值遍历是我们最常用的方式,一般长这样

$arr = [0,1,2,3];
foreach ($arr as $key => $value) {
    var_dump($value);
}

值遍历操作的是数组的副本,如果在遍历的过程中修改了数组,不会影响遍历结果,比如

$arr = [0,1,2,3];
foreach ($arr as $key => $value) {
    var_dump($value);
    $arr[3] = 8;
}

//结果为   int(0) int(1) int(2) int(3),php5和php7都这样

遍历的过程中虽然修改了$arr[3]的值为8,但是最终遍历出的结果还是3

引用遍历

引用遍历是在$value前加&,一般长这样

$arr = [0,1,2,3];
foreach ($arr as $key => &$value) {
    var_dump($value);
    $arr[3] = 8;
}

//结果 int(0) int(1) int(2) int(8),php5和php7都这样

遍历的结果已经是修改过的值了

关于遍历后$value

无论是值遍历还是引用遍历,遍历结束后$value都不会释放,不同的地方在于,值遍历$value是个副本,修改了不影响数组最后一个元素,但是引用遍历的话,$value为指向数组最后一个元素的指针,如果修改了$value值,会影响数组最后一个元素,比如

//值遍历
$arr = [0,1,2,3];
foreach ($arr as $key => $value) {
    // var_dump($value);
}

var_dump($value); //$value为3,是元素最后一个元素副本
$value = 8;
var_dump($value); //$value为8
var_dump($arr[3]); //最后一个元素还是3

//引用遍历
$arr = [0,1,2,3];
foreach ($arr as $key => &$value) {
    // var_dump($value);
}

var_dump($value); //$value为指向数组最后一个元素的指针
$value = 8;
var_dump($value); //$value为8
var_dump($arr[3]); //最后一个元素也变成了8

如果你觉得你理解了,你可以看看下面的结果是啥

$arr = [0,1,2,3];
foreach ($arr as $key => &$value) {
    
}
foreach ($arr as $key => $value) {
    
}

var_dump($arr);

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

第一次遍历结束后,$value指向了数组的最后一个元素,第二次遍历过程中,最后一个元素依次变成0,1,2,当遍历到最后一个元素$arr[3]时,此时它已经变成了2。

php7的变化

php7以前,foreach使用的是数组的内部指针

$arr = [0,1,2,3];
foreach ($arr as $key => $value) {
    
}

var_dump(current($arr)); // php5结果:bool(false),php7结果:int(0)

php5环境下,遍历后指针超出元素范围,php7没有用数组内部指针,所以指针还是指向第一个元素。但是注意,每次foreach开始时都会重置数组指针到第一个元素,相当于调用了reset()方法。所以,php5环境下,多次foreach同一个元素并没有什么问题,每次遍历开始都从第一个元素开始。

参考

foreach
migration70.incompatible.foreach

原文地址:https://www.cnblogs.com/whyly/p/13535042.html