Loops: while, for and foreach

Repeat work without repeating code, and control loops with break and continue.

  • Beginner
  • 4 min read
  • Updated 17 Oct 2026

What you will learn

  • Repeat code with while and for
  • Iterate over arrays with foreach, including keys
  • Skip and stop iterations with continue and break
  • Recognise and avoid infinite loops

Loops run the same block of code several times. Listing products, sending a batch of emails, reading lines from a file: all loops.

while

A while loop repeats as long as its condition is true:

PHP
<?php

$countdown = 3;

while ($countdown > 0) {
    echo $countdown, PHP_EOL;
    $countdown--;
}

echo 'Lift off!';
Plain text
3
2
1
Lift off!

The condition is checked before each pass. If it is false from the start, the body never runs.

If nothing inside the loop ever makes the condition false, the loop runs forever. Remove $countdown--; above and the script hangs until PHP's time limit stops it. When a script seems stuck, look for a loop variable that never changes.

do-while

do-while checks the condition after the body, so the body always runs at least once:

PHP
<?php

do {
    $roll = random_int(1, 6);
    echo "Rolled {$roll}", PHP_EOL;
} while ($roll !== 6);

for

for is ideal when you know how many times to repeat. It packs the setup, condition and update into one line:

PHP
<?php

for ($i = 1; $i <= 5; $i++) {
    echo "Line {$i}", PHP_EOL;
}

The three parts are:

  1. $i = 1 runs once, before the loop starts.
  2. $i <= 5 is checked before each pass.
  3. $i++ runs after each pass.

You can count in other steps too: for ($i = 10; $i >= 0; $i -= 2) counts down in twos.

foreach: the loop you will use most

foreach walks through every element of an array without managing an index:

PHP
<?php

$languages = ['PHP', 'JavaScript', 'Python'];

foreach ($languages as $language) {
    echo $language, PHP_EOL;
}

To get keys as well as values, use key => value:

PHP
<?php

$prices = [
    'coffee' => 2.80,
    'tea' => 2.20,
    'cake' => 3.50,
];

foreach ($prices as $item => $price) {
    printf("%-8s £%.2f\n", $item, $price);
}
Plain text
coffee   £2.80
tea      £2.20
cake     £3.50

For indexed arrays, the key is the position, which is handy for numbering:

PHP
<?php

$steps = ['Install PHP', 'Write a script', 'Run it'];

foreach ($steps as $index => $step) {
    echo ($index + 1) . ". {$step}", PHP_EOL;
}

break and continue

continue skips the rest of the current pass. break leaves the loop entirely:

PHP
<?php

$numbers = [4, 7, -1, 12, 0, 9];

foreach ($numbers as $n) {
    if ($n < 0) {
        continue; // Ignore negative numbers.
    }

    if ($n === 0) {
        break; // Zero marks the end of the data.
    }

    echo $n, PHP_EOL;
}
Plain text
4
7
12

Loops in HTML templates

In templates, PHP has an alternative syntax that reads better between HTML tags:

PHP
<?php $todos = ['Buy milk', 'Learn loops', 'Walk the dog']; ?>

<ul>
    <?php foreach ($todos as $todo): ?>
        <li><?= htmlspecialchars($todo) ?></li>
    <?php endforeach; ?>
</ul>

htmlspecialchars() escapes the text so it cannot break your HTML. You will see why that matters in the forms lesson.

Which loop should I use?

SituationLoop
Every item in an arrayforeach
A known number of repetitionsfor
Until something happenswhile
At least once, then until something happensdo-while

Summary

  • while repeats while a condition is true; make sure something changes it.
  • do-while always runs at least once.
  • for suits counting; foreach suits arrays and is the most common.
  • continue skips a pass, break exits the loop.
  • Use foreach (...): and endforeach; inside HTML templates.

Further reading