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
continueis hit), control returns to step 1 and the condition is checked again. - If a
breakis 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
forwhen you know the exact number of iterations up front; reservewhilefor cases where the stopping point depends on runtime data. - Prefer
foreachover a manualwhileloop 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...whileinstead ofwhilewhen 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
whileloop that prints every even number from 2 to 20, inclusive, each on its own line. - Given
$stack = [5, 3, 8, 1, 9, 2];, use awhileloop witharray_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
whileloop 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.
breakexits the loop immediately;continueskips to the next condition check.- The loop’s stopping condition must actually change inside the body, or the loop will run forever.
- Use
whilewhen the number of iterations isn’t known in advance; useforwhen it is, andforeachfor straightforward array iteration.
