## *foreach*
(PHP 4, PHP 5, PHP 7)
*foreach* 语法结构提供了遍历数组的简单方式。*foreach* 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。有两种语法:
~~~
foreach (array_expression as $value)
statement
foreach (array_expression as $key => $value)
statement
~~~
第一种格式遍历给定的 *array\_expression* 数组。每次循环中,当前单元的值被赋给 *$value* 并且数组内部的指针向前移一步(因此下一次循环中将会得到下一个单元)。
第二种格式做同样的事,只除了当前单元的键名也会在每次循环中被赋给变量 *$key*。
还能够自定义[遍历对象](http://php.net/manual/zh/language.oop5.iterations.php)。
> **Note**:
> 当 *foreach* 开始执行时,数组内部的指针会自动指向第一个单元。这意味着不需要在 *foreach* 循环之前调用 [reset()](http://php.net/manual/zh/function.reset.php)。
> 由于 *foreach* 依赖内部数组指针,在循环中修改其值将可能导致意外的行为。
可以很容易地通过在 *$value* 之前加上 & 来修改数组的元素。此方法将以[引用](http://php.net/manual/zh/language.references.php)赋值而不是拷贝一个值。
```
<?php
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
$value = $value * 2;
}
// $arr is now array(2, 4, 6, 8)
unset($value); // 最后取消掉引用
?>
```
*$value* 的引用仅在被遍历的数组可以被引用时才可用(例如是个变量)。以下代码则无法运行:
```
<?php
foreach (array(1, 2, 3, 4) as &$value) {
$value = $value * 2;
}
?>
```
**Warning**
数组最后一个元素的 *$value* 引用在 *foreach* 循环之后仍会保留。建议使用 [unset()](http://php.net/manual/zh/function.unset.php) 来将其销毁。
> **Note**:
> *foreach* 不支持用“@”来抑制错误信息的能力。
用户可能注意到了以下的代码功能完全相同:
```
<?php
$arr = array("one", "two", "three");
reset($arr);
while (list(, $value) = each($arr)) {
echo "Value: $value<br>\n";
}
foreach ($arr as $value) {
echo "Value: $value<br />\n";
}
?>
```
以下代码功能也完全相同:
```
<?php
$arr = array("one", "two", "three");
reset($arr);
while (list($key, $value) = each($arr)) {
echo "Key: $key; Value: $value<br />\n";
}
foreach ($arr as $key => $value) {
echo "Key: $key; Value: $value<br />\n";
}
?>
```
示范用法的更多例子:
```
<?php
/* foreach example 1: value only */
$a = array(1, 2, 3, 17);
foreach ($a as $v) {
echo "Current value of \$a: $v.\n";
}
/* foreach example 2: value (with its manual access notation printed for illustration) */
$a = array(1, 2, 3, 17);
$i = 0; /* for illustrative purposes only */
foreach ($a as $v) {
echo "\$a[$i] => $v.\n";
$i++;
}
/* foreach example 3: key and value */
$a = array(
"one" => 1,
"two" => 2,
"three" => 3,
"seventeen" => 17
);
foreach ($a as $k => $v) {
echo "\$a[$k] => $v.\n";
}
/* foreach example 4: multi-dimensional arrays */
$a = array();
$a[0][0] = "a";
$a[0][1] = "b";
$a[1][0] = "y";
$a[1][1] = "z";
foreach ($a as $v1) {
foreach ($v1 as $v2) {
echo "$v2\n";
}
}
/* foreach example 5: dynamic arrays */
foreach (array(1, 2, 3, 4, 5) as $v) {
echo "$v\n";
}
?>
```
### 用 list() 给嵌套的数组解包
(PHP 5 >= 5.5.0, PHP 7)
PHP 5.5 增添了遍历一个数组的数组的功能并且把嵌套的数组解包到循环变量中,只需将 [list()](http://php.net/manual/zh/function.list.php) 作为值提供。
例如:
```
<?php
$array = [
[1, 2],
[3, 4],
];
foreach ($array as list($a, $b)) {
// $a contains the first element of the nested array,
// and $b contains the second element.
echo "A: $a; B: $b\n";
}
?>
```
以上例程会输出:
~~~
A: 1; B: 2
A: 3; B: 4
~~~
[list()](http://php.net/manual/zh/function.list.php) 中的单元可以少于嵌套数组的,此时多出来的数组单元将被忽略:
```
<?php
$array = [
[1, 2],
[3, 4],
];
foreach ($array as list($a)) {
// Note that there is no $b here.
echo "$a\n";
}
?>
```
以上例程会输出:
~~~
1
3
~~~
如果 [list()](http://php.net/manual/zh/function.list.php) 中列出的单元多于嵌套数组则会发出一条消息级别的错误信息:
```
<?php
$array = [
[1, 2],
[3, 4],
];
foreach ($array as list($a, $b, $c)) {
echo "A: $a; B: $b; C: $c\n";
}
?>
```
以上例程会输出:
~~~
Notice: Undefined offset: 2 in example.php on line 7
A: 1; B: 2; C:
Notice: Undefined offset: 2 in example.php on line 7
A: 3; B: 4; C:
~~~
- 序言
- 简介
- PHP是什么?
- PHP能做什么?
- 基本语法
- 类型
- boolean(布尔型)
- integer(整型)
- float(浮点型)
- string(字符串)
- array(数组)
- object(对象)
- callable(可调用)
- resource(资源)
- NULL(无类型)
- 伪类型
- 类型转换的判别
- 变量
- 基础
- 预定义变量
- 变量范围
- 可变变量
- 来自PHP之外的变量
- 常量
- 语法
- 魔术常量
- 表达式
- 运算符
- 运算符优先级
- 算术运算符
- 赋值运算符
- 位运算符
- 比较运算符
- 错误控制运算符
- 执行运算符
- 递增/递减运算符
- 逻辑运算符
- 字符串运算符
- 数组运算符
- 类型运算符
- 流程控制
- if
- else
- elseif/else if
- 流程控制的替代语法
- while
- do-whille
- for
- foreach
- break
- continue
- switch
- declare
- return
- require
- include
- require_once
- include_once
- goto
- 函数
- 用户自定义函数
- 函数的参数
- 返回值
- 可变函数
- 内部 (内置)函数
- 匿名函数
- 类与对象
- 简介
- 基本概念
- 属性
- 类的自动加载
- 构造函数
- 访问控制(可见性)