$arr = array(0,1,2,3,4,5);
$ref = &$arr;
foreach($arr as $value){
$arr = array();
echo $value;
}
在 PHP7.0 中, 输出 012345, 而在 PHP 5 中 输出 0. PHP7.0 提及到 foreach 改变的有三点.
看到第二点有点懵, 我看一些资料都说 PHP 5 在 foreach 是操作数组副本的, 那么官方手册写这句话有什么含义还是有所变化? 为何会导致 PHP7.0 和 PHP 5 的结果截然不同?
1
carlclone 2018-04-18 22:09:20 +08:00
二、按照值进行循环的时候,foreach 是对该数组的拷贝操作
foreach 按照值进行循环的时候(by-value),foreach 是对该数组的一个拷贝进行操作。这样在循环过程中对数组做的修改是不会影响循环行为的。 $array = [0, 1, 2]; $ref =& $array; // Necessary to trigger the old behavior foreach ($array as $val) { var_dump($val); unset($array[1]); } http://www.jb51.net/article/91331.htm 这里第二点 , 以前应该不是拷贝了 |
2
WytheHuang OP @carlclone 但是, PHP 5 以前不是拷贝的话, 那么下面这个代码应该跟 PHP 7 不一样
``` $arr = array('a','b','c'); foreach ($arr as $key=> $value) { $arr[] = 'd'; print_r($arr); var_dump($key,$value); } ``` 然而输出其结果也是一样的. > Array ( [0] => a [1] => b [2] => c [3] => d ) int(0) string(1) "a" Array ( [0] => a [1] => b [2] => c [3] => d [4] => d ) int(1) string(1) "b" Array ( [0] => a [1] => b [2] => c [3] => d [4] => d [5] => d ) int(2) string(1) "c" 而且上面代码$ref = &$array 为什么会出现这样结果, 不是很明白. |
3
jfcherng 2018-04-18 23:05:08 +08:00
2. foreach by-value operates on a copy of the array
When used in the default by-value mode, foreach will now operate on a copy of the array being iterated rather than the array itself. This means that changes to the array made during iteration will not affect the values that are iterated. 把完整的官方說明看完啊,不要只看標題 |
4
WytheHuang OP |
5
DukeAnn 2018-04-19 10:18:09 +08:00
PHP 7 你可以这么理解,`foreach` 把整个数组隐式的镜像了一份给自己用,所以无论你怎么修改原数组都不会影响到 `foreach` 镜像数据,但是你打出来你原始数组是已经被修改了的。
```php $arr = array(0,1,2,3,4,5); $ref = &$arr; foreach($arr as $key => $value){ $arr = array(); echo "foreach 镜像数据:" . $value; echo "\n"; echo "原始数组:"; var_dump($arr); } ``` 运行结果: foreach 镜像数据:0 原始数组:array(0) { } foreach 镜像数据:1 原始数组:array(0) { } foreach 镜像数据:2 原始数组:array(0) { } foreach 镜像数据:3 原始数组:array(0) { } foreach 镜像数据:4 原始数组:array(0) { } foreach 镜像数据:5 原始数组:array(0) { } |
6
WytheHuang OP @DukeAnn PHP 7 这样可以理解, 而在 PHP 5 中的, 加了引用. 情况有所不同的, 实时随着数组改变的, 就是这一点让我觉得很郁闷.
``` // PHP 输出: foreach 镜像数据:0 原始数组:array(0) { } $arr = array(0,1,2,3,4,5); $ref = &$arr; foreach($arr as $key => $value){ $arr = array(); echo "foreach 镜像数据:" . $value; echo "\n"; echo "原始数组:"; var_dump($arr); } ``` |
7
DukeAnn 2018-04-19 10:42:03 +08:00
@WytheHuang 这个没看具体文档,但是根据当前输出的情况和最近看 Go 语言的遍历机制,我推测 php5 应该是只缓存了当前遍历这一次的 $value 和 $key,而且遍历会改变原始数组的内部指针位置从而拿到下一个需要遍历的键值对,进行镜像。所以在 foreach 内部将数组赋值为空,第二次遍历就凉了。
|
8
DukeAnn 2018-04-19 10:43:13 +08:00
@WytheHuang 个人推测,具体的可以自己实践一下,或者查查文档。
|