Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 39 additions & 76 deletions language/control-structures/for.xml
Original file line number Diff line number Diff line change
Expand Up @@ -142,97 +142,60 @@ endfor;
</informalexample>
</para>
<simpara>
It's common for many users to iterate through arrays like in the
example below.
Expressions <varname>expr2</varname> and <varname>expr3</varname> are
evaluated every iteration. It's advisable to use simple expressions in these
places to avoid performance issues. For example, if the number of iterations
is known in advance, it is better to use a variable instead of a function call
in <varname>expr2</varname>:
</simpara>
<para>
<informalexample>
<programlisting role="php">
<programlisting role="php" annotations="non-interactive">
<![CDATA[
<?php
/*
* This is an array with some data we want to modify
* when running through the for loop.
*/
$people = array(
array('name' => 'Kalle', 'salt' => 856412),
array('name' => 'Pierre', 'salt' => 215863)
);

for($i = 0; $i < count($people); ++$i) {
$people[$i]['salt'] = random_int(100000, 999999);
$people = ['Kalle', 'Pierre'];

// Bad practice: calling a function on every iteration
for($i = 0; $i < getIterationCount($people); ++$i) {
$people[$i] .= ' is cool';
}
var_dump($people);
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
array(2) {
[0]=>
array(2) {
["name"]=>
string(5) "Kalle"
["salt"]=>
int(454478)
}
[1]=>
array(2) {
["name"]=>
string(6) "Pierre"
["salt"]=>
int(776978)
}

// Good practice: storing the count in a variable
for($i = 0, $peopleCount = getIterationCount($people); $i < $peopleCount; ++$i) {
$people[$i] .= ' is cool';
}

]]>
</screen>
</programlisting>
</informalexample>
</para>
<simpara>
The above code can be slow, because the array size is fetched on
every iteration. Since the size never changes, the loop can be easily
In the example above, the invoked function always returns the same value.
Since the size never changes, the loop can be easily
optimized by using an intermediate variable to store the size instead
of repeatedly calling <function>count</function>:
of repeatedly calling the same function. An added benefit is that the
number of iterations is now constant, which helps avoid bugs when the
array is modified during the loop.
</simpara>
<para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$people = array(
array('name' => 'Kalle', 'salt' => 856412),
array('name' => 'Pierre', 'salt' => 215863)
);

for($i = 0, $size = count($people); $i < $size; ++$i) {
$people[$i]['salt'] = random_int(100000, 999999);
}
var_dump($people);
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
array(2) {
[0]=>
array(2) {
["name"]=>
string(5) "Kalle"
["salt"]=>
int(454478)
}
[1]=>
array(2) {
["name"]=>
string(6) "Pierre"
["salt"]=>
int(776978)
}
}
]]>
</screen>
</informalexample>
</para>
<note>
<simpara>
The size of an <type>array</type> is stored with the array, which means that
calling the built-in function <function>count</function> does not require
counting the elements and does not cause performance issues. However, care
should be taken when using <function>count</function> on objects implementing
<interfacename>Countable</interfacename>, as such calls can be more expensive.
</simpara>
</note>

<note>
<simpara>
The <literal>for</literal> loop is not the recommended way to
iterate over arrays. The &foreach; loop is specifically
designed for this purpose and is usually more convenient.
</simpara>
</note>
</sect1>

<!-- Keep this comment at the end of the file
Expand Down