## *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
- 函數
- 用戶自定義函數
- 函數的參數
- 返回值
- 可變函數
- 內部 (內置)函數
- 匿名函數
- 類與對象
- 簡介
- 基本概念
- 屬性
- 類的自動加載
- 構造函數
- 訪問控制(可見性)