Reader Stacks

break and continue in PHP: What They Actually Do

break exits the loop entirely; continue skips just the current iteration — a small distinction that's easy to mix up, plus the numeric-argument form for breaking out of nested loops.

break and continue both change a loop's normal flow, but in genuinely different ways — mixing them up is a common source of off-by-one logic bugs.

break — exits the loop entirely

for ($i = 0; $i < 10; $i++) {
    if ($i === 5) {
        break;
    }
    echo $i; // prints 0 1 2 3 4
}

Once break runs, the loop stops immediately — no further iterations happen, even if the loop's normal condition would still be true.

continue — skips just the current iteration

for ($i = 0; $i < 10; $i++) {
    if ($i % 2 === 0) {
        continue;
    }
    echo $i; // prints 1 3 5 7 9
}

continue jumps straight to the loop's next iteration (re-checking the condition, running any increment step) without executing the rest of the current iteration's code — the loop keeps running, just skipping specific passes.

Breaking out of nested loops

Both break and continue accept an optional numeric argument specifying how many levels of enclosing loop structure to break out of or continue:

for ($i = 0; $i < 3; $i++) {
    for ($j = 0; $j < 3; $j++) {
        if ($j === 1) {
            break 2; // breaks out of BOTH loops, not just the inner one
        }
        echo "$i,$j ";
    }
}

Without the 2, a plain break only exits the innermost loop, and the outer loop would continue iterating — this is a real, easy-to-miss bug when nested loops are involved.

In switch statements

break is also what ends a case in a switch statement — omitting it causes "fall-through" into the next case, which is sometimes intentional but is a classic source of bugs when it's accidental. continue inside a switch that's itself inside a loop behaves like break for the switch (PHP treats a bare switch as one loop level for this purpose) — using continue 2 is the explicit way to actually continue the outer loop from inside a switch case.

continue in while loops has a different-looking control point

In a for loop, continue still runs the loop's increment expression before the next condition check. In a while loop there is no separate increment phase, so any state update you placed at the bottom of the body is skipped. That can accidentally create an infinite loop:

$i = 0;

while ($i < 5) {
    if ($i === 2) {
        continue; // $i never changes again
    }

    $i++;
}

The safe version updates the loop state before the branch, or structures the condition so the update cannot be bypassed:

$i = 0;

while ($i < 5) {
    $i++;

    if ($i === 2) {
        continue;
    }

    echo $i;
}

break works in switch and loop structures, but return is different

break only leaves the current loop or switch level. return leaves the entire function or method immediately. If a loop is inside a helper function and finding one matching value means the function is finished, return is often clearer than setting a flag, breaking, and then checking the flag afterward.

function findAdmin(array $users): ?array
{
    foreach ($users as $user) {
        if ($user['role'] === 'admin') {
            return $user;
        }
    }

    return null;
}

Numeric levels are powerful but easy to make opaque

break 2 and continue 2 are legitimate PHP syntax, but once nesting becomes deeper than two levels the number starts encoding structure that a reader has to count manually. At that point, extracting the inner search into a function and returning a value is usually easier to maintain than a break 3 several screens away from the loops it controls.

Topics: Developer Productivity