PHP Loops (while, do while, foreach & for) Tutorial

In this tutorial, we learn how to control the flow of our application even further. We learn how PHP can help us iterate through sections of code with while, do-while, for and foreach loop statements.

We also cover so called nested loops, which are loops inside other loops. And finally, we compare each loop and explain when to use which one.

What is iteration control flow?

By default, the flow of an application written in PHP is sequential. It starts at the top and flows sequentially to the bottom. Many times we will need to alter this flow and allow specific sections of code to be repeated multiple times.

For this purpose, PHP offers us various types of iteration, or looping, logic which are capable of repeating sections of code. Iteration helps us with repetitive tasks and when dealing with big data.

As an example, let’s consider a database for a mailing list which contains entries for a name and email address.

When we want to send an email to everyone on the list, we will need to iterate through all the users in the database one by one. We then fetch their email address and send them an email.

Example: simple loop concept
<?php

// for every user in the database
    // send email

?>

The interpreter will start at the first user and send an email to that user. If there are more users in the database, it will process the next user in the database and send them an email too.

This process loops over and over for all the users in the database, or until we tell it to stop.

PHP offers us four types of loop statements:

  • for loop
  • foreach loop
  • while loop
  • do-while loop
While loop

A while loop will tell the interpreter to execute its code block repeatedly, as long as the while expression remains true. The expression will be evaluated each time at the beginning of the loop’s iteration.

The basic form of a while loop is as follows.

Syntax:
while (expression) {
    execution statement
}
Example: while loop
<?php

$i = 1;

while ($i <= 10) {
    echo $i . "<br>";
    $i++;
}

?>

Let’s break down the example above step by step:

  1. First we have a variable with a numerical value of 1. This variable will be our counter in the loop and allow us to stop it.
  2. The expression is a conditional evaluation that checks if the value of $i is less than or equal to 10.
  3. Next, we echo the number to keep things simple.
  4. Then we increment our counter with $i++. This is the same as $i = i + 1 , so $i will effectively increment each time the loop runs until it becomes 10, which can be seen when the application runs in the browser.

If we do not increment the counter, the loop will keep iterating because it will always be below 10. This is known as an infinite loop and will severely slow down the application until it eventually crashes.

Do-While loop

A do-while loop is similar to a while loop, except that the expression is checked at the end of the each iteration instead of the beginning. This ensures that the loop will always run at least once.

To put it simply, a do-while loop is an upside down while loop.

Syntax:
do {
    execution code
} while (expression);

The code we want to execute if the while expression is true, is placed within the do execution block. It will always execute at least once, even if the while expression is false.

We must also remember to terminate the do-while statement with a semicolon.

Example: do-while loop with a true expression
<?php

$i = 1;

do {
    echo $i . "<br>";
    $i++;
} while ($i <= 10);

?>

The example above produces the same result as the while loop example earlier in this tutorial, echoing the numbers 1 through 10.

We’ve mentioned that a do-while loop will run at least once, even if the while expression is false. This happens because the expression is checked after the first execution.

Let’s consider the same example as above, but in this case the while expression will always be false.

Example: do-while loop with a false expression
<?php

$i = 1;

do {
    echo $i . "<br>";
    $i++;
} while (false);

?>

The example above will echo the number once, then stop because it finds the while expression to be false. The interpreter will then move on to the next piece of code below the loop.

For loop

We can think of a for loop as a condensed version of the while loop. A for loop has the counter and increment/decrement built-in as expressions.

Syntax:
for (counter; condition; counter_inc/decr) {
    execution statement
}

This may seem somewhat confusing at first, let’s consider an example and then do a break down of what happens.

Example: for loop
<?php
//   counter   condition   counter increment/decrement
for ($i = 1;   $i <= 10;   $i++) {
    echo $i . "<br>";
}

?>

The example above is the same as the while and do-while loops.

Let’s do a breakdown of the expressions in the for loop:

  • The first expression sets up the counter ($i = 1) In the while loop this counter was outside and above the loop.
  • The second expression is our condition ($i <= 10). This was the main expression in the while loop.
  • The third expression is where we increment or decrement the counter. This was done inside the while loop execution block.

The for loop is a nice, compact version of the while loop which doesn’t allow us to forget to set or increment/decrement the counter.

However, because of its syntax, the for loop has some limitations against the while loop which we discuss further below.

Foreach loop

The foreach loop is an easy way to iterate over collection sets like arrays. In fact, foreach loops in PHP only work on arrays and objects and will raise an error if we try to use it with another data type.

The foreach loop has two types of syntaxes. We can work with either just the array values or the key/value pairs.

Syntax:
// only values
foreach (expression as $value) {
    execution statement
}

// key/value pairs
foreach (expression as $key => $value) {
    execution statement
}

On each iteration of the foreach loop, the value of the current array element is assigned to the temporary variable $value.

The internal array pointer is then automatically incremented so there is no need for any incremental variable to exist.

Example: foreach loop using only values
<?php

// Array
$num = array(1, 2, 3, 4, 5);

// Foreach
foreach ($num as $item) {
    echo $item . "<br>";
}

?>

In the example above we start to loop through the array at the first array element. We assign that specific element in the $num array to the temporary variable $item, which we can then perform operations with, like echo it out to the browser.

The statement reads as follows:
foreach $num array element as $item_temp_variable, execute statement(s)

Let’s look at some more examples of looping through arrays.

Example: change array element in foreach loop
<?php

// Array
$num = array(1, 2, 3, 4, 5);

// Foreach
foreach ($num as $item) {
    echo $item += 50;
    echo "<br>";
}

?>

The example above will add 50 to each number in the array.

Example: access and modify key/value array pairs in foreach loop
<?php

// Key/Value Array
$num = array(
    "One" => 1,
    "Two" => 2,
    "Ten" => 10
);

// Foreach access key/value
foreach ($num as $key => $value) {
    echo "Key: " . $key . " => Value: " . $value;
    echo "<br>";
}

echo "<br>";

// Foreach modify key/value
foreach ($num as $key => $value) {
    echo "Key: " . $key . " => Value: " . $value += 50;
    echo "<br>";
}

?>

In the first foreach loop of the example above, we can access each key/value pair by assigning the individual keys and values to the temp variables $key and $value.

In the second foreach loop of the example above, we modify the value of the key/value pair by adding 50 to the number.

Nested loops

We can place loops inside each other, nesting them. The interpreter will parse the code hierarchically by parsing the first iteration of the outside loop, then all the iterations of the inside loop, before returning to the outside loop for its next iteration.

As an example, let’s consider the popular game Minecraft. Its world consists of rectangular blocks that are generated in what are called chunks. A chunk consists of 16 blocks on each axis, x, y and z. To generate one of these chunks we would need to loop through each one of the axes.

Example: nested loop
<?php

$chunkSize = 16;

for ($z = 0; $z <= $chunkSize; $z++) {
    // generate blocks on z axis
    generateFaces(z);

    for ($y = 0; $y <= $chunkSize; $y++) {
        // generate blocks on y axis
        generateFaces(y);

        for ($x = 0; $x <= $chunkSize; $x++) {
            // generate blocks on x axis
            generateFaces(x);
        }
    }
}

?>

The example above is not quite the same as it would be done in a real world scenario, it is also overly simplified and unoptimized specifically for the example of multiple nested loops.

The basic idea is that we generate a block on each axis of the chunk, therefore we need to loop through each axes inside each axis, requiring three nested loops.

As a general rule of thumb, if we need to nest more than three times, we should consider a different approach to the problem and refactor our code.

Alternative loop syntax

Just like with conditional control structures, iteration control structures can also be written with alternative syntax. It’s exactly the same concept as discussed in Alternative if/switch syntax with only the keywords that change.

Just in case you forgot, here is how to write the alternative syntax.

Syntax: if statement alternative syntax
if (expression):
    execution block
endif;

While the syntax above shows an if statement, the concept remains the same. With loops we will simply change the end keywords to:

  • while = endwhile
  • for = endfor
  • foreach = endforeach

There is no alternative syntax for a do-while loop.

Let’s look at some examples for the different loop alternative syntax cases.

Example: while loop alternative syntax
<?php

$i = 1;

while ($i <= 10):
    echo $i . "<br>";
    $i++;
endwhile;

?>
Example: for loop alternative syntax
<?php

for ($i = 1; $i <= 10; $i++):
    echo $i . "<br>";
endfor;

?>
Example: foreach loop with alternative syntax
<?php

$num = array(1, 2, 3, 4, 5);

foreach ($num as $item):
    echo $item . "<br>";
endforeach;

?>
while vs do-while vs for vs foreach

Which of the loops do we use for which occasion? It really depends on the code we are working with at that time.

As a general rule of thumb, we can use these loops for the following situations:

  • A while loop is used when we don’t know explicitly how many times the loop should run.
  • A do-while loop is used when we don’t know explicitly how many times the loop should run, and if we want the code to execute at least once.
  • A for loop is used when we know how many times the loop should run.
  • A foreach loop is used when we are working with collections of items, such as arrays.
Summary: Points to remember
  • Iteration control is used to repeatedly execute sections of code.
  • A while loop continues to execute while the expression is true and needs some sort of counter.
  • A do-while loop evaluates the expression after the loop and will always execute at least once.
  • A for loop is a condensed version of the while loop, and has a counter built-in.
  • A foreach loop iterates only over collection sets like arrays and objects.
  • We can nest loops inside other loops. However, if we find ourselves nesting more than 3 times, we should consider refactoring our code.