do...while Loop
Most loops in PHP check their condition before running the body, which means the body might execute zero times. The do...while loop flips that order: it runs the body first, and only checks the condition afterward, when the first pass is already done. That makes it a post-test loop, and the guarantee it gives you — "this code runs at least once" — is exactly the tool you reach for when a task must happen up front and only repeats if some condition demands it, like retrying a failed operation or showing a menu at least one time before deciding whether to show it again.
Basic syntax
The structure looks like a while loop turned inside out: the do keyword introduces the body, and the condition comes after the closing brace, inside a while (...). The one detail that trips people up is the trailing semicolon after that closing parenthesis — it is required, and PHP will throw a parse error without it.
do...while skeleton
<?php
do {
// body: runs first, unconditionally
} while (condition); // <-- semicolon is mandatory hereThe body always runs at least once
Here is the clearest way to see the behavior: start a counter at a value that already fails the condition, and watch the body execute anyway.
Condition is false from the start
<?php
$count = 10;
do {
echo "Count is {$count}\n";
$count++;
} while ($count < 5);Count is 10
Even though $count < 5 is false before the loop ever starts, the body still runs exactly once, printing Count is 10, before the condition is checked and the loop exits.
do...while vs. while, side by side
Swap the same logic into a plain while loop and the difference becomes concrete: while checks the condition before the first iteration, so if it starts out false, the body never runs at all.
Same condition, while loop this time
<?php
$count = 10;
while ($count < 5) {
echo "Count is {$count}\n";
$count++;
}
echo "Loop finished.\n";Loop finished.
Nothing is printed from inside the loop — the condition failed on the very first check, so the body was skipped entirely. That single line of difference (check-before vs. check-after) is the whole reason do...while exists as a separate construct rather than just being syntactic sugar for while.
A normal case: counting up
For a condition that starts out true, do...while behaves just like a while loop would — the difference only shows up in the edge case above. Here is the everyday version, counting from 1 to 5.
Counting with do...while
<?php
$i = 1;
do {
echo "i = {$i}\n";
$i++;
} while ($i <= 5);i = 1 i = 2 i = 3 i = 4 i = 5
Real use case: retrying a connection attempt
A common real-world pattern is retry logic: you always want to attempt an operation at least once, and only loop again if it failed and you have retries left. That "try first, decide after" shape maps directly onto do...while. Below, a fake connection function succeeds on its third attempt, simulated with a counter instead of real networking.
Retrying a flaky connection up to 5 times
<?php
function attemptConnection(int $attemptNumber): bool
{
// Pretend the "server" only accepts the connection on attempt 3.
return $attemptNumber === 3;
}
$attempt = 0;
$maxAttempts = 5;
$connected = false;
do {
$attempt++;
echo "Attempt {$attempt}: connecting...\n";
$connected = attemptConnection($attempt);
if (!$connected) {
echo " Failed, will retry.\n";
}
} while (!$connected && $attempt < $maxAttempts);
if ($connected) {
echo "Connected on attempt {$attempt}.\n";
} else {
echo "Giving up after {$maxAttempts} attempts.\n";
}Attempt 1: connecting... Failed, will retry. Attempt 2: connecting... Failed, will retry. Attempt 3: connecting... Connected on attempt 3.
Notice the loop guard is !$connected && $attempt < $maxAttempts: it
keeps going only while the connection has not succeeded and there
are attempts left. Because it is a do...while, the very first
attempt happens unconditionally — there is no need to special-case
"try once before entering the loop."
Real use case: a simulated menu loop
Interactive command-line tools often show a menu, act on the user's pick, and keep showing the menu until the user chooses "exit." The menu must appear at least once — you cannot know the user wants to quit before you have even shown them the options — which again makes do...while the natural fit. Real input would come from something like readline(), but the shape below simulates a sequence of choices with an array so the example runs top to bottom.
Menu loop driven by simulated input
<?php
$simulatedInputs = ['1', '2', '3']; // stand-in for real user input
$inputIndex = 0;
$choice = null;
do {
echo "== Menu ==\n";
echo "1) Show status\n";
echo "2) Show version\n";
echo "3) Exit\n";
$choice = $simulatedInputs[$inputIndex] ?? '3';
$inputIndex++;
switch ($choice) {
case '1':
echo "Status: OK\n";
break;
case '2':
echo "Version: 8.3\n";
break;
case '3':
echo "Goodbye!\n";
break;
}
} while ($choice !== '3');== Menu == 1) Show status 2) Show version 3) Exit Status: OK == Menu == 1) Show status 2) Show version 3) Exit Version: 8.3 == Menu == 1) Show status 2) Show version 3) Exit Goodbye!
Nesting and skipping iterations
do...while supports break and continue exactly like while and for do. break exits the loop immediately, and continue jumps straight to the condition check — it does not skip back to the top of the body without checking the condition first.
continue jumps to the condition, not the top of the body
<?php
$n = 0;
do {
$n++;
if ($n % 2 === 0) {
continue; // skips the echo below, then checks the while condition
}
echo "Odd number: {$n}\n";
} while ($n < 6);Odd number: 1 Odd number: 3 Odd number: 5
When to reach for it
Use
do...whilewhen the body must run at least once regardless of the condition, such as an initial attempt, a first menu display, or a validation prompt.Use a plain
whileloop when the condition should be allowed to skip the body entirely on the first check — for example, processing a list that might already be empty.Use a
forloop when you know in advance how many iterations you want, or when the loop variable, condition, and increment naturally belong together on one line.