1
0
mirror of https://github.com/php/doc-zh.git synced 2026-03-24 07:02:15 +01:00
Files
2025-11-15 23:05:58 +08:00

317 lines
7.6 KiB
XML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: ba7093cf7f30dbcd301c62536ac7ef8664d891f4 Maintainer: dallas Status: ready -->
<!-- CREDITS: mowangjuanzi -->
<sect1 xml:id="control-structures.foreach" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>foreach</title>
<?phpdoc print-version-for="foreach"?>
<para>
<literal>foreach</literal> 结构提供了一种遍历 <type>array</type><interfacename>Traversable</interfacename>
object 的简便方式。当用于其他数据类型的变量,或未初始化的变量时,<literal>foreach</literal> 会触发错误。
<informalexample>
<simpara>
<literal>foreach</literal> 可选择性的获取每个元素的 <literal>key</literal>
</simpara>
<programlisting>
<![CDATA[
foreach (iterable_expression as $value) {
statement_list
}
foreach (iterable_expression as $key => $value) {
statement_list
}
]]>
</programlisting>
</informalexample>
</para>
<simpara>
第一种格式遍历给定的 <literal>iterable_expression</literal>
迭代器。每次循环中,当前单元的值被赋给 <literal>$value</literal>
</simpara>
<simpara>
第二种格式做同样的事,只除了当前单元的键名也会在每次循环中被赋给变量
<literal>$key</literal>
</simpara>
<simpara>
注意 <literal>foreach</literal> 不会修改类似 <function>current</function>
<function>key</function> 函数所使用的数组内部指针。
</simpara>
<simpara>
还能够自定义<link linkend="language.oop5.iterations">遍历对象</link>
</simpara>
<example>
<title>常见的 <literal>foreach</literal> 用法</title>
<programlisting role="php">
<![CDATA[
<?php
/* 示例:仅有值 */
$array = [1, 2, 3, 17];
foreach ($array as $value) {
echo "Current element of \$array: $value.\n";
}
/* 示例key 和值 */
$array = [
"one" => 1,
"two" => 2,
"three" => 3,
"seventeen" => 17
];
foreach ($array as $key => $value) {
echo "Key: $key => Value: $value\n";
}
/* 示例:多维 key-value 数组 */
$grid = [];
$grid[0][0] = "a";
$grid[0][1] = "b";
$grid[1][0] = "y";
$grid[1][1] = "z";
foreach ($grid as $y => $row) {
foreach ($row as $x => $value) {
echo "Value at position x=$x and y=$y: $value\n";
}
}
/* 示例:动态数组 */
foreach (range(1, 5) as $value) {
echo "$value\n";
}
?>
]]>
</programlisting>
</example>
<note>
<para>
<literal>foreach</literal> 不支持使用 <link
linkend="language.operators.errorcontrol"><literal>@</literal></link> 运算符来抑制错误消息。
</para>
</note>
<sect2 xml:id="control-structures.foreach.list">
<title>解包嵌套数组</title>
<?phpdoc print-version-for="foreach.list"?>
<para>
可以通过遍历数组中的数组,在 value 的位置使用<link
linkend="language.types.array.syntax.destructuring">数组解构</link><literal>[]</literal>)或
<function>list</function> 语言结构将嵌套数组解包到循环变量中。
<note>
<simpara>
请注意,通过 <literal>[]</literal> 进行<link
linkend="language.types.array.syntax.destructuring">数组解构</link>仅在 PHP 7.1.0 及以上版本中可用。
</simpara>
</note>
</para>
<para>
<informalexample>
<simpara>
在以下两个示例中,将设 <literal>$a</literal> 为嵌套数组的第一个元素,<literal>$b</literal> 将包含第二个元素:
</simpara>
<programlisting role="php">
<![CDATA[
<?php
$array = [
[1, 2],
[3, 4],
];
foreach ($array as [$a, $b]) {
echo "A: $a; B: $b\n";
}
foreach ($array as list($a, $b)) {
echo "A: $a; B: $b\n";
}
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
A: 1; B: 2
A: 3; B: 4
]]>
</screen>
</informalexample>
</para>
<para>
当提供的变量数量少于数组中的元素数量时,将会忽略多余的元素。类似地,可通过使用逗号跳过某些元素:
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$array = [
[1, 2, 5],
[3, 4, 6],
];
foreach ($array as [$a, $b]) {
// 注意此处没有 $c
echo "$a $b\n";
}
foreach ($array as [, , $c]) {
// 跳过 $a 和 $b
echo "$c\n";
}
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
1 2
3 4
5
6
]]>
</screen>
</informalexample>
</para>
<para>
如果数组元素数量不足以填充 <function>list</function>,将生成一条 notice 级别的错误消息。
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$array = [
[1, 2],
[3, 4],
];
foreach ($array as [$a, $b, $c]) {
echo "A: $a; B: $b; C: $c\n";
}
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
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:
]]>
</screen>
</informalexample>
</para>
</sect2>
<sect2 xml:id="control-structures.foreach.reference">
<title>foreach 和引用</title>
<para>
可以通过在 <literal>$value</literal> 前加上
<literal>&amp;</literal>,就可以在循环中直接修改数组元素。此时,值将以<link
linkend="language.references">引用</link>的方式赋值。
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$arr = [1, 2, 3, 4];
foreach ($arr as &$value) {
$value = $value * 2;
}
// $arr is now [2, 4, 6, 8]
unset($value); // 断开与最后一个元素的引用
?>
]]>
</programlisting>
</informalexample>
</para>
<warning>
<simpara>
对数组最后一个元素的 <literal>$value</literal> 的引用在 <literal>foreach</literal>
循环结束后仍然存在。建议使用 <function>unset</function> 将其销毁,否则将出现以下行为:
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$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);
}
// ……最终会复制倒数第二个值到最后一个值上
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
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 )
]]>
</screen>
</informalexample>
</warning>
<example>
<title>通过引用遍历常量数组的值</title>
<programlisting role="php">
<![CDATA[
<?php
foreach ([1, 2, 3, 4] as &$value) {
$value = $value * 2;
}
?>
]]>
</programlisting>
</example>
</sect2>
<sect2 role="seealso">
&reftitle.seealso;
<simplelist>
<member><link linkend="language.types.array">array</link></member>
<member><interfacename>Traversable</interfacename></member>
<member><link linkend="language.types.iterable">iterable</link></member>
<member><function>list</function></member>
</simplelist>
</sect2>
</sect1>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->