php-doc-en/language/control-structures/foreach.xml
Adam Harvey 8ad0d94e1c Add initial migration guide for PHP 5.5.
What's done: the migration guide itself, updates to existing functions and
functionality, and new language features.

What's not done: stub pages for new functions and methods. (I'd rather get this
in now, though, than have it languish on my hard drive any longer so that other
people can contribute.)

What could use help: the generator chapter is pretty rough and ready. Better
examples would be awesome. I certainly won't argue if somebody wants to add the
function stubs, either.


git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@328430 c90b9560-bf6c-de11-be94-00142212c4b1
2012-11-20 15:17:23 +00:00

331 lines
7.1 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<sect1 xml:id="control-structures.foreach" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title><literal>foreach</literal></title>
<?phpdoc print-version-for="foreach"?>
<para>
The <literal>foreach</literal> construct provides an easy way to
iterate over arrays. <literal>foreach</literal> works only on arrays
and objects, and will issue an error when you try to use it on a variable
with a different data type or an uninitialized variable. There are two
syntaxes:
<informalexample>
<programlisting>
<![CDATA[
foreach (array_expression as $value)
statement
foreach (array_expression as $key => $value)
statement
]]>
</programlisting>
</informalexample>
</para>
<simpara>
The first form loops over the array given by
<literal>array_expression</literal>. On each iteration, the value of
the current element is assigned to <literal>$value</literal> and
the internal array pointer is advanced by one (so on the next
iteration, you'll be looking at the next element).
</simpara>
<simpara>
The second form will additionally assign the current element's key to
the <literal>$key</literal> variable on each iteration.
</simpara>
<simpara>
It is possible to
<link linkend="language.oop5.iterations">customize object iteration</link>.
</simpara>
<para>
<note>
<para>
When <literal>foreach</literal> first starts executing, the
internal array pointer is automatically reset to the first element
of the array. This means that you do not need to call
<function>reset</function> before a <literal>foreach</literal>
loop.
</para>
<para>
As <literal>foreach</literal> relies on the internal array pointer changing it
within the loop may lead to unexpected behavior.
</para>
</note>
</para>
<para>
In order to be able to directly modify array elements within the loop precede
<literal>$value</literal> with &amp;. In that case the value will be assigned by
<link linkend="language.references">reference</link>.
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
$value = $value * 2;
}
// $arr is now array(2, 4, 6, 8)
unset($value); // break the reference with the last element
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
Referencing <literal>$value</literal> is only possible if the iterated array can be
referenced (i.e. if it is a variable). The following code won't work:
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
foreach (array(1, 2, 3, 4) as &$value) {
$value = $value * 2;
}
?>
]]>
</programlisting>
</informalexample>
</para>
<warning>
<para>
Reference of a <literal>$value</literal> and the last array element
remain even after the <literal>foreach</literal> loop. It is recommended
to destroy it by <function>unset</function>.
</para>
</warning>
<para>
<note>
<para>
<literal>foreach</literal> does not support the ability to
suppress error messages using '@'.
</para>
</note>
</para>
<para>
You may have noticed that the following are functionally
identical:
<informalexample>
<programlisting role="php">
<![CDATA[
<?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";
}
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
The following are also functionally identical:
<informalexample>
<programlisting role="php">
<![CDATA[
<?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";
}
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
Some more examples to demonstrate usage:
<informalexample>
<programlisting role="php">
<![CDATA[
<?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";
}
?>
]]>
</programlisting>
</informalexample>
</para>
<sect2 xml:id="control-structures.foreach.list">
<title>Unpacking nested arrays with list()</title>
<?phpdoc print-version-for="foreach.list"?>
<para>
PHP 5.5 added the ability to iterate over an array of arrays and unpack the
nested array into loop variables by providing a <function>list</function>
as the value.
</para>
<para>
For example:
<informalexample>
<programlisting role="php">
<![CDATA[
<?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";
}
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
A: 1; B: 2
A: 3; B: 4
]]>
</screen>
</informalexample>
</para>
<para>
You can provide fewer elements in the <function>list</function> than there
are in the nested array, in which case the leftover array values will be
ignored:
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$array = [
[1, 2],
[3, 4],
];
foreach ($array as list($a)) {
// Note that there is no $b here.
echo "$a\n";
}
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
1
3
]]>
</screen>
</informalexample>
</para>
<para>
A notice will be generated if there aren't enough array elements to fill
the <function>list</function>:
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$array = [
[1, 2],
[3, 4],
];
foreach ($array as list($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>
</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
-->