1. 简介
foreach
语法结构提供了遍历数组的简单方式。foreach
仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。
2. 语法
foreach
有两种语法:
foreach (array_expression as $value)
statement
第一种格式遍历给定的 array_expression 数组。每次循环中,当前单元的值被赋给 $value 并且数组内部的指针向前移一步(因此下一次循环中将会得到下一个单元)。
foreach (array_expression as $key => $value)
statement
第二种格式也一样,还会把当前单元的键名在每次循环中赋给变量 $key。
还能够自定义遍历对象。
3. 注意
3.1 迭代时不再改变内部数组指针
在 PHP7 之前,当数组通过 foreach 迭代时,数组指针会移动。但现在 foreach 不再改变内部数组指针。
$arr = [0, 1, 2];
foreach ($arr as &$value) {
var_dump(current($arr));
}
/** 结果
int 0
int 0
int 0
*/
3.2 通过值遍历时,操作的值为数组的副本
当默认使用值来遍历数组时,foreach 实际操作的是数组的迭代副本,而非数组本身。这就意味着,foreach 中的操作不会修改原数组的值。
3.3 通过引用遍历时,有更好的迭代特性
当使用引用引用来遍历数组时,foreach 在迭代中能更好的跟踪数组的变化。例如,在迭代中添加一个值到数组中:
$arr = [0];
foreach ($arr as &$value) {
var_dump($value);
$arr[1] = 1;
}
/** 结果
int 0
int 1
*/
3.4 通过引用遍历时的陷阱
通过引用遍历数组时,迭代结束,但对最后一个元素的引用还保留着。建议使用 unset()
来将其销毁。否则可能影响后面的结果。
$arr = [1, 2, 3, 4];
foreach ($arr as &$value) {
$value = $value * 2;
}
// $arr 现在是 [2, 4, 6, 8]
// 没有执行 unset($value),$value 仍然是最后一个元素 $arr[3] 的引用
foreach ($arr as $key => $value) {
// $arr[3] 将依次被 $arr 里面的值更新
echo "{$key} => {$value} ";
print_r($arr);
}
// 直到最后倒数第二个值被赋值给最后一个值。因为倒数第二次时,第三个元素和最后一个元素的值已经是一样的了。
/** 结果
0 => 2 Array
(
[0] => 2
[1] => 4
[2] => 6
[3] => 2
)
1 => 4 Array
(
[0] => 2
[1] => 4
[2] => 6
[3] => 4
)
2 => 6 Array
(
[0] => 2
[1] => 4
[2] => 6
[3] => 6
)
3 => 6 Array
(
[0] => 2
[1] => 4
[2] => 6
[3] => 6
)
*/
解决办法:
- 在遍历结束时,使用
unset()
将引用变量销毁。 - 第二次遍历时,使用其他变量名,别用
$value
了。 - 第二次遍历也用引用
&
。