Loops

PHP · Lesson 13 of 50 6 min read Updated

Computers are good at doing the same thing many times without getting bored. Printing every student in a class, adding up every item in a cart, showing 12 months of EMI payments: all of these need a loop, a block of code that repeats.

In this lesson you will learn PHP's four loops (while, do...while, for and foreach), how to stop or skip with break and continue, and how to use loops inside HTML templates.

while

A while loop repeats its block as long as its condition is true. PHP checks the condition before each round, which is called an iteration:

PHP
<?php
declare(strict_types=1);

$target = 5000;
$saved = 0;
$weeks = 0;

while ($saved < $target) {
    $saved += 750;
    $weeks++;
}

echo "Saved ₹$saved in $weeks weeks\n";
Output
Saved ₹5250 in 7 weeks

Use while when you do not know in advance how many rounds you need: here, how many weeks of saving ₹750 it takes to reach ₹5,000.

Something inside the loop must eventually make the condition false. If you forget $saved += 750;, the condition stays true forever. This is an infinite loop. On a web server, PHP stops a script after 30 seconds by default; in the terminal there is no limit, so press Ctrl+C to stop it.

do...while

A do...while loop checks its condition after each round, so the block always runs at least once:

PHP
<?php
declare(strict_types=1);

$i = 10;

do {
    echo "Runs once with i = $i\n";
} while ($i < 5);
Output
Runs once with i = 10

The condition is false from the start, but the block still ran once. do...while is rare in everyday PHP; it suits tasks like "try something, then check whether to try again".

for

A for loop is built for counting. Its brackets hold three parts separated by semicolons: a starting step, a condition checked before each round, and an update that runs after each round.

PHP
<?php
declare(strict_types=1);

$amount = 10_000;

for ($year = 1; $year <= 5; $year++) {
    $amount = $amount * 1.07;
    echo "Year $year: ₹", number_format($amount, 2), "\n";
}
Output
Year 1: ₹10,700.00
Year 2: ₹11,449.00
Year 3: ₹12,250.43
Year 4: ₹13,107.96
Year 5: ₹14,025.52

This shows ₹10,000 growing at 7% a year. Read the for line as: "start $year at 1; keep going while $year is 5 or less; add 1 after each round".

foreach

foreach walks through every item of an array, one at a time. It is the loop you will use most in PHP, because so much data (database rows, form fields, JSON) arrives as arrays. You can take just the values, or the keys and values together with $key => $value:

PHP
<?php
declare(strict_types=1);

$marks = ['Maths' => 88, 'Science' => 92, 'English' => 79, 'Hindi' => 85];
$total = 0;

foreach ($marks as $subject => $score) {
    echo "$subject: $score\n";
    $total += $score;
}

echo "Total: $total out of ", count($marks) * 100, "\n";
Output
Maths: 88
Science: 92
English: 79
Hindi: 85
Total: 344 out of 400

For a simple list without meaningful keys, write foreach ($cities as $city). You will learn much more about arrays in Arrays.

break and continue

Two keywords change the normal flow of any loop:

  • continue skips the rest of the current round and moves to the next one.
  • break leaves the loop completely.
PHP
<?php
declare(strict_types=1);

$attendance = [
    'Aarav' => 72,
    'Priya' => null,
    'Kabir' => 45,
    'Meera' => 28,
    'Rohan' => 91,
];

foreach ($attendance as $name => $score) {
    if ($score === null) {
        echo "$name was absent, skipping\n";
        continue;
    }
    if ($score < 33) {
        echo "$name needs extra classes. Search finished.\n";
        break;
    }
    echo "$name scored $score\n";
}
Output
Aarav scored 72
Priya was absent, skipping
Kabir scored 45
Meera needs extra classes. Search finished.

Rohan is never checked, because break ended the loop at Meera. Inside nested loops, break 2 leaves two levels at once.

Nested loops

A loop can contain another loop. The inner loop runs completely for every round of the outer loop. This builds grids, such as seat numbers in a hall:

PHP
<?php
declare(strict_types=1);

$rows = ['A', 'B', 'C'];

foreach ($rows as $row) {
    $line = '';
    for ($seat = 1; $seat <= 4; $seat++) {
        $line .= "$row$seat ";
    }
    echo trim($line), "\n";
}
Output
A1 A2 A3 A4
B1 B2 B3 B4
C1 C2 C3 C4

Nested loops multiply the work: 3 rows times 4 seats is 12 rounds. With large arrays, a loop inside a loop can become slow, so keep an eye on the sizes.

Loops in HTML templates

Like if, loops have an alternative syntax for templates: a colon after the brackets and endforeach; (or endfor;, endwhile;) at the end.

PHP
<?php
declare(strict_types=1);

$cities = ['Rohtak', 'Jaipur', 'Pune'];
?>
<ul>
<?php foreach ($cities as $city): ?>
  <li><?= htmlspecialchars($city) ?></li>
<?php endforeach; ?>
</ul>
Output
<ul>
  <li>Rohtak</li>
  <li>Jaipur</li>
  <li>Pune</li>
</ul>

The browser shows a bulleted list of the three cities. htmlspecialchars() keeps the output safe if a value ever contains HTML characters.

Common mistakes

  • Off-by-one errors. for ($i = 1; $i < 10; $i++) runs 9 times, not 10. Check whether you need < or <=.
  • Forgetting to update the condition in while. The loop never ends. Make sure something inside changes the condition.
  • Changing an array while looping over it. foreach works on a copy of the array, so changes to the loop variable do not reach the original. Build a new array instead.
  • Reusing a reference variable. If you write foreach ($prices as &$price) to edit items in place, call unset($price); after the loop. Otherwise a later loop that reuses $price overwrites your last item.

Key points

  • while checks the condition before each round; do...while checks after, so it runs at least once.
  • for is best for counting, with a start, a condition and an update.
  • foreach loops over arrays, with $value or $key => $value.
  • continue skips to the next round; break exits the loop.
  • Every loop must be able to end; infinite loops freeze your script.
  • In templates, use foreach (...): and endforeach;, and escape output with htmlspecialchars().

Exercise

A shop sells items with these prices: ['Notebook' => 60, 'Pen' => 15, 'Geometry box' => 0, 'School bag' => 899, 'Water bottle' => 249]. A price of 0 means the item is out of stock. Write a foreach loop that skips out-of-stock items with continue, prints each other item and its price, and keeps a running total. Stop the loop with break as soon as the total goes above ₹1,000, and print the final total.

Show solution
PHP
<?php
declare(strict_types=1);

$prices = [
    'Notebook' => 60,
    'Pen' => 15,
    'Geometry box' => 0,
    'School bag' => 899,
    'Water bottle' => 249,
];
$total = 0;

foreach ($prices as $item => $price) {
    if ($price === 0) {
        continue;
    }
    echo "$item: ₹$price\n";
    $total += $price;
    if ($total > 1000) {
        break;
    }
}

echo "Total: ₹$total\n";
Output
Notebook: ₹60
Pen: ₹15
School bag: ₹899
Water bottle: ₹249
Total: ₹1223

The geometry box is skipped by continue. After the school bag the total is ₹974, which is not above ₹1,000, so the loop carries on. The water bottle takes it to ₹1,223, and break stops the loop; any items after it would never be printed.

Quick Quiz

1. Which loop always runs its block at least once?

2. How many times does for ($i = 0; $i < 5; $i++) run?

3. What does continue do inside a loop?

4. Which syntax prints an array as an HTML list most cleanly in a template?

Learn PHP with a mentor

Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call