PHP While Loop

The while loop is one of PHP’s core control structures for repeating a block of code as long as a given condition remains true. Unlike a for loop, which is built around a known number of iterations, while is the tool to reach for when you don’t know in advance how many times you’ll need to repeat something — reading rows from a database until there are none left, draining a queue, or retrying an operation until it succeeds. Mastering while means understanding exactly when PHP checks the condition, how values are converted to true or false, and how to avoid the classic trap of an infinite loop.

Overview: How the While Loop Works

A while loop is a pretest loop (also called an entry-controlled loop): PHP evaluates the condition before every iteration, including the very first one. If the condition is falsy the very first time it’s checked, the loop body never executes at all — not even once. This is the key difference from a do...while loop, which always runs its body at least once because it checks the condition afterward.

Internally, when the Zend Engine compiles a while statement, it generates two key jump instructions around the loop body: one that evaluates the condition and jumps past the loop entirely if it’s falsy (roughly a jump-if-false opcode), and one at the end of the body that jumps back up to re-evaluate the condition (an unconditional jump opcode). This is exactly why the condition is always re-checked before each pass — the engine literally returns to that check every time execution reaches the closing brace, until the jump-if-false instruction finally fires and execution continues past the loop.

The condition itself can be any PHP expression — a comparison, a function call, a variable, or a complex boolean expression — and PHP converts its result to a boolean using the standard “truthy/falsy” rules. The following values are considered falsy (and will stop or prevent a loop from running): the boolean false, the integer 0 and float 0.0, the empty string "" and the string "0", an empty array [], and null. Every other value — including the string "0.0", non-empty arrays, and objects — is truthy. Getting this conversion right matters enormously for loops, because a subtle truthy/falsy mismatch is a common source of off-by-one errors and infinite loops.

Syntax

The basic form of a while loop looks like this:

while (condition) {
    // statements to repeat
}

PHP also supports an alternate syntax, often preferred when a loop is mixed with HTML output in a template file, replacing the braces with a colon and endwhile;:

while (condition):
    // statements to repeat
endwhile;
Part Purpose
condition Any expression, evaluated and converted to boolean before each iteration. The loop continues while it’s truthy.
{ ... } or : ... endwhile; The loop body — one or more statements executed each time the condition is true.
break; Immediately exits the loop, skipping any remaining iterations.
continue; Skips the rest of the current iteration’s body and jumps back to re-checking the condition.

Examples

Example 1: Counting Up

<?php
$count = 1;
while ($count <= 5) {
    echo "Count: $count" . PHP_EOL;
    $count++;
}

Output:

Count: 1
Count: 2
Count: 3
Count: 4
Count: 5

PHP checks $count <= 5 before every iteration. As soon as $count becomes 6, the condition evaluates to false and the loop stops — the increment $count++ at the end of the body is what guarantees the loop eventually terminates.

Example 2: Draining a Task Queue

<?php
$tasks = ["Backup database", "Send newsletter", "Clear cache", "Generate report"];
$taskNumber = 1;

while (!empty($tasks)) {
    $currentTask = array_shift($tasks);
    echo "Task {$taskNumber}: {$currentTask}" . PHP_EOL;
    $taskNumber++;
}

echo "All tasks completed." . PHP_EOL;

Output:

Task 1: Backup database
Task 2: Send newsletter
Task 3: Clear cache
Task 4: Generate report
All tasks completed.

Here the condition isn’t a simple counter — it’s !empty($tasks), which stays true as long as the array has elements. array_shift() removes and returns the first element each time, shrinking the array until it’s empty and the condition becomes falsy. This pattern is common whenever you’re processing a queue whose size you don’t know ahead of time.

Example 3: Generating a Fibonacci Sequence

<?php
$limit = 50;
$a = 0;
$b = 1;

echo "Fibonacci numbers below {$limit}: ";

while ($a < $limit) {
    echo $a . " ";
    [$a, $b] = [$b, $a + $b];
}

echo PHP_EOL;

Output:

Fibonacci numbers below 50: 0 1 1 2 3 5 8 13 21 34 

This example shows a condition based on a computed value rather than a manually incremented counter. Each iteration recalculates $a and $b using list assignment, and the loop naturally stops once the sequence crosses the limit — there’s no way to know in advance exactly how many iterations that will take, which is precisely the situation while is designed for.

How It Works Step by Step

Every while loop follows the same execution sequence:

  • PHP evaluates the condition expression.
  • The result is converted to a boolean using truthy/falsy rules.
  • If it’s true, the loop body runs from top to bottom.
  • If it’s false, execution jumps to the first statement after the loop, and the body is skipped entirely.
  • After the body finishes (or a continue is hit), control returns to step 1 and the condition is checked again.
  • If a break is hit anywhere in the body, the loop exits immediately, regardless of what the condition would evaluate to.

Because the condition is re-evaluated fresh on every pass, anything referenced in it must actually change inside the loop body — otherwise the condition’s truthiness never changes and the loop either never runs or never stops. This is also why functions like array_shift(), which mutate the array being tested by empty(), work correctly as loop conditions: the state the condition depends on is genuinely changing each iteration.

Common Mistakes

Mistake 1: Forgetting to Update the Loop Variable

The single most common while loop bug is writing a condition that depends on a variable, then never changing that variable inside the loop:

$i = 1;
while ($i <= 5) {
    echo $i;
}
// $i is never incremented, so $i <= 5 is always true — infinite loop

Since $i stays 1 forever, the condition $i <= 5 never becomes false, and the script hangs until it hits PHP’s execution time limit. The fix is to make sure every code path through the loop body eventually moves the condition closer to false:

<?php
$i = 1;
while ($i <= 5) {
    echo $i;
    $i++;
}
echo PHP_EOL;

Output:

12345

Mistake 2: Using = Instead of ==

A single equals sign is assignment, not comparison. Using it inside a condition doesn’t compare anything — it overwrites the variable and then tests whatever value was just assigned:

$attempts = 0;
while ($attempts = 3) {
    echo "Attempt {$attempts}" . PHP_EOL;
    break;
}
// $attempts = 3 assigns 3 (truthy) instead of comparing — the intent to
// check a value is lost, and without the break this would loop forever

The condition should compare two values with ==, ===, <, >, or similar operators, not assign with a single =:

<?php
$attempts = 0;
$maxAttempts = 3;

while ($attempts < $maxAttempts) {
    echo "Attempt " . ($attempts + 1) . PHP_EOL;
    $attempts++;
}

Output:

Attempt 1
Attempt 2
Attempt 3

Mistake 3: Off-by-One Errors with Array Indexes

Array indexes are zero-based, so a loop bound with <= against count() reaches one index too far:

$colors = ['red', 'green', 'blue'];
$i = 0;
while ($i <= count($colors)) {
    echo $colors[$i] . PHP_EOL;
    $i++;
}
// count($colors) is 3, but valid indexes are only 0, 1, and 2 —
// $i reaches 3 and accesses an undefined array key, triggering a warning

Using a strict < comparison against count() keeps the loop within the array’s valid bounds:

<?php
$colors = ['red', 'green', 'blue'];
$i = 0;

while ($i < count($colors)) {
    echo $colors[$i] . PHP_EOL;
    $i++;
}

Output:

red
green
blue

Best Practices

  • Always make sure something inside the loop body moves the condition toward false — a counter increment, an array shrinking, or a value changing state.
  • Prefer for when you know the exact number of iterations up front; reserve while for cases where the stopping point depends on runtime data.
  • Prefer foreach over a manual while loop with array pointer functions when simply iterating over an array — it’s clearer and less error-prone.
  • Use === or an explicit comparison operator in conditions instead of relying on implicit type juggling.
  • When a loop depends on external or untrusted input (like a value from a database or API), consider adding a safety counter or maximum iteration cap to guard against runaway loops.
  • Use do...while instead of while when the body must run at least once regardless of the initial condition.
  • Keep loop bodies focused — if the body grows large or deeply nested, extract logic into a well-named function to keep the loop itself easy to read.
  • Use the alternate while (...): ... endwhile; syntax only inside templates that mix HTML and PHP; use braces everywhere else.

Practice Exercises

  • Write a while loop that prints every even number from 2 to 20, inclusive, each on its own line.
  • Given $stack = [5, 3, 8, 1, 9, 2];, use a while loop with array_pop() to print each value from the end of the array until it’s empty, prefixing each with “Popped: “.
  • Write a countdown that starts at 10 and counts down to 1, printing each number, then prints “Liftoff!” once the loop finishes.

Summary

  • A while loop repeats its body for as long as its condition remains truthy, checking the condition before every iteration, including the first.
  • If the condition is falsy on the first check, the loop body never runs at all.
  • The condition can be any expression; PHP converts the result using standard truthy/falsy rules.
  • break exits the loop immediately; continue skips to the next condition check.
  • The loop’s stopping condition must actually change inside the body, or the loop will run forever.
  • Use while when the number of iterations isn’t known in advance; use for when it is, and foreach for straightforward array iteration.