Lesson 44 of 100
Loops15 min5 checksPHP 8.5

Break and Continue in Loops

Learn how break stops a loop, how continue skips one iteration, and how to combine them to filter records and enforce a limit.

01 · THE IDEAREAD → TRY → LEARN

Why loop control matters

A loop normally visits every item. Real data is messier. Some records are invalid and should be ignored. Some inputs contain a sentinel that means "nothing after this counts". Sometimes you only need the first few results. PHP gives you two statements for these cases: continue and break.

  • continue abandons the current iteration and moves on to the next one.
  • break ends the whole loop immediately.

Both work in for, foreach, while and do-while. break also works in switch.

Stopping with break

Use break when continuing would be pointless or wrong. In this example the word stop marks the end of the useful data.

Example
<?php
$words = ['one', 'two', 'stop', 'three'];
foreach ($words as $word) {
    if ($word === 'stop') {
        break;
    }
    echo $word, "\n";
}
Output
one
two

The loop prints one and two. When it reaches stop, execution jumps to the first statement after the loop. three is never visited.

Skipping with continue

Use continue when one item should be ignored but later items still matter. A guard clause at the top of the loop body keeps the main logic flat and readable.

Example
<?php
$values = [1, 2, 3, 4, 5, 6];
$odd = [];
foreach ($values as $value) {
    if ($value % 2 === 0) {
        continue;
    }
    $odd[] = $value;
}
echo json_encode($odd), "\n";
Output
[1,3,5]

Even numbers hit continue, so the append line is skipped for them. Only 1, 3 and 5 are collected.

Nested loops and the numeric argument

Both statements accept an optional number saying how many enclosing structures they affect. The default is 1. break 2 leaves the inner loop and the outer loop together.

Example
<?php
$rows = [[1, 2, 3], [4, -1, 6], [7, 8, 9]];
$seen = [];
foreach ($rows as $row) {
    foreach ($row as $n) {
        if ($n < 0) {
            break 2;
        }
        $seen[] = $n;
    }
}
echo json_encode($seen), "\n";
Output
[1,2,3,4]

Without the 2, only the inner loop would end and the third row would still be processed. Remember that a switch counts as a loop structure for this purpose. Inside a switch that sits in a loop, break leaves only the switch, and continue 2 is how you move to the next iteration of the surrounding loop.

Putting the pieces together

A common pattern combines three rules in one loop:

  1. A sentinel value ends processing with break.
  2. Invalid items are skipped with continue.
  3. Once enough results are collected, break again.

Order matters. Check the sentinel before the validity test, otherwise the sentinel itself may be silently skipped as invalid. Check the limit right after adding an item so you never collect more than requested. Handle a limit of zero or less before the loop starts, because a check placed after an append would still let one item through.

Common mistakes

  • Using continue when you meant break, so the loop keeps going past a stop marker.
  • Forgetting the numeric argument in nested loops.
  • Using loose comparison for a sentinel. Prefer ===, since 0 == 'stop' has surprised many people in older PHP versions.
  • Putting a limit check at the end of the loop body after code that can continue, so the check is sometimes skipped.

Exercise contract

Write collect_valid(array $items, int $limit): array.

  • Walk $items in order.
  • If an item is exactly the string 'stop', end the loop.
  • Skip every item that is not an integer, or that is a negative integer. Floats, booleans and other strings are not valid. Zero is valid.
  • Append each valid integer to the result.
  • Stop as soon as the result holds $limit items.
  • If $limit is 0 or less, return an empty array.

The tests compare the returned array, so do not echo anything. Think about which rule needs break and which needs continue, and put the sentinel check first.

Recap

continue skips one iteration, break ends the loop, and a number after either one reaches out through nested structures. Used as early guard clauses, they keep loops short and make stopping conditions easy to see.

Before you start

Functions · Arrays · Types

You’ll practice
  • Skip invalid records and stop at a deterministic limit
  • Implement and test a deterministic PHP 8.4 function
Your task

Make collect_valid() pass all 5 checks. Run your code as often as you like, then check your answer.

exercise.phpSaved in this browserPHP 8.5
CONSOLE & CHECKS● Ready

Ready when you are

Your output will appear here.
Make it work. Then make it pass.

PHP loads on your first run. Each check starts fresh. Your code stays in this browser; clearing site data removes your progress. A check or the task looks wrong? Report a problem with this exercise.