Continue Statement

Yo Yogesh.M Updated 17 Oct 2026
7 min read ·Lesson 28 of 102
In this post

What Is continue ? In simple terms: continue skips the rest of the current loop iteration and moves on to the next one. The loop itself keeps running. Technically: continue ends the current iteration

What Is continue?

In simple terms: continue skips the rest of the current loop iteration and moves on to the next one. The loop itself keeps running.

Technically: continue ends the current iteration of a for, foreach, while, or do...while loop. Control jumps to the point where the loop decides whether to run again: the update and condition in a for loop, the condition in while/do...while, or the next element in foreach. An optional numeric argument (continue 2) applies this to an enclosing loop.

continue vs break

StatementWhat Happens
continueSkip this item, keep looping
breakStop the whole loop

Why It Is Needed

When processing a list, some items should simply be skipped — invalid records, inactive users, empty lines, items already handled. continue handles these cases at the top of the loop body, so the main processing code does not need to be wrapped in an if block.


Syntax

continue;      // next iteration of the innermost loop
continue 2;    // next iteration of the loop one level up

Example: Skipping Odd Numbers

<?php
for ($i = 1; $i <= 10; $i++) {
    if ($i % 2 !== 0) {
        continue;
    }

    echo $i . ' ';
}
echo "\n";

Output

2 4 6 8 10 

How It Works

  1. For odd numbers, $i % 2 !== 0 is true and continue runs.
  2. The echo below is skipped for that iteration.
  3. In a for loop, the update $i++ still runs after continue, then the condition is checked again.
  4. Even numbers reach the echo.

continue as a Guard Clause in Loops

Without continue, filtering often leads to nested blocks:

foreach ($users as $user) {
    if ($user['active']) {
        if ($user['email'] !== '') {
            // ... main processing, deeply indented ...
        }
    }
}

With continue, each skip condition is handled up front, and the main work stays at the top indentation level:

<?php
$users = [
    ['name' => 'Asha', 'email' => 'asha@example.com', 'active' => true],
    ['name' => 'Bala', 'email' => '', 'active' => true],
    ['name' => 'Charu', 'email' => 'charu@example.com', 'active' => false],
    ['name' => 'Dev', 'email' => 'dev@example', 'active' => true],
    ['name' => 'Esha', 'email' => 'esha@example.com', 'active' => true],
];

$sent = 0;

foreach ($users as $user) {
    if (!$user['active']) {
        echo "Skipping {$user['name']}: inactive\n";
        continue;
    }

    if (filter_var($user['email'], FILTER_VALIDATE_EMAIL) === false) {
        echo "Skipping {$user['name']}: invalid email\n";
        continue;
    }

    echo "Sending newsletter to {$user['email']}\n";
    $sent++;
}

echo "Sent: $sent\n";

Output

Sending newsletter to asha@example.com
Skipping Bala: invalid email
Skipping Charu: inactive
Skipping Dev: invalid email
Sending newsletter to esha@example.com
Sent: 2

Why This Structure Works Well

  • Each reason for skipping is written once, with a clear message.
  • The main action (sending) is not nested inside any if.
  • Adding a new skip rule means adding one more guard at the top.

This is the loop equivalent of guard clauses with return in functions (see PHP Nested if).


continue in while Loops: The Infinite Loop Trap

In a for loop, the update expression runs automatically after continue. In a while loop, there is no separate update step — if the counter is updated at the end of the body, continue skips that update:

// WARNING: infinite loop
$i = 0;
while ($i < 5) {
    if ($i === 2) {
        continue;   // $i++ below is skipped, so $i stays 2 forever
    }
    echo $i;
    $i++;
}

When $i reaches 2, continue jumps back to the condition without increasing $i, so the loop repeats with $i === 2 forever.

Fix: Update Before continue

<?php
$i = 0;

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

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

    echo $i . ' ';
}
echo "\n";

Output

1 2 4 5 

Moving $i++ to the start of the body guarantees it runs in every iteration. (Because the increment now happens first, the loop prints 1 to 5 instead of 0 to 4.) Alternatively, use a for loop, where the update is always executed.


continue 2 in Nested Loops

A plain continue affects the innermost loop. continue 2 skips the rest of the current iteration of the outer loop — including any remaining inner iterations.

Example: Skip an Entire Order When One Item Is Invalid

<?php
$orders = [
    ['id' => 1, 'items' => [['sku' => 'A', 'qty' => 2], ['sku' => 'B', 'qty' => 1]]],
    ['id' => 2, 'items' => [['sku' => 'C', 'qty' => 0], ['sku' => 'D', 'qty' => 3]]],
    ['id' => 3, 'items' => [['sku' => 'E', 'qty' => 1]]],
];

foreach ($orders as $order) {
    foreach ($order['items'] as $item) {
        if ($item['qty'] <= 0) {
            echo "Order {$order['id']} skipped: invalid quantity for {$item['sku']}\n";
            continue 2;
        }
    }

    echo "Order {$order['id']} is valid\n";
}

Output

Order 1 is valid
Order 2 skipped: invalid quantity for C
Order 3 is valid

How It Works

  • For order 2, the first item C has quantity 0.
  • continue 2 immediately moves to the next order: item D is not checked, and the line "Order 2 is valid" after the inner loop is skipped.
  • A plain continue would only skip to the next item, and order 2 would then be reported as valid.

The rules for the argument are the same as for break: it must be a positive integer literal, and a switch counts as one level.

continue Inside switch

Inside a switch within a loop, a plain continue targets the switch, which behaves like break. PHP warns about this at compile time ("continue" targeting switch is equivalent to "break"). Use continue 2 to move to the loop's next iteration:

<?php
foreach (['INFO ok', 'DEBUG verbose', 'ERROR failed'] as $line) {
    switch (strtok($line, ' ')) {
        case 'DEBUG':
            continue 2;   // skip debug lines entirely
        case 'ERROR':
            echo "!! ";
            break;
    }

    echo $line . "\n";
}

Output

INFO ok
!! ERROR failed

The DEBUG line is skipped completely; ERROR lines get a marker before the line is printed.


continue vs array_filter()

When the goal is only to select items, array_filter() can replace a loop with continue:

<?php
$scores = [78, 0, 92, 45, 0, 88];

$valid = [];
foreach ($scores as $score) {
    if ($score === 0) {
        continue;
    }
    $valid[] = $score;
}

$alsoValid = array_values(array_filter($scores, fn($score) => $score !== 0));

echo implode(', ', $valid) . "\n";
echo implode(', ', $alsoValid) . "\n";

Output

78, 92, 45, 88
78, 92, 45, 88
  • array_filter() keeps elements for which the callback returns true.
  • It preserves the original keys, so array_values() re-indexes the result from 0.

Use array_filter() for pure selection, and a loop with continue when each item needs further processing, logging, or several skip rules with different messages.


Common Mistakes

Skipping the Counter Update in while Loops

Effect: Infinite loop.

Fix: Update the counter before any continue, or use for.

Using continue When break Was Intended

Effect: The loop keeps running after the item you were looking for was found.

Fix: Use break to stop the loop; continue only skips one item.

Plain continue Inside switch

Effect: Acts like break; the rest of the loop body still runs.

Fix: Use continue 2.

Too Many Skip Conditions Scattered Through the Body

Effect: Hard to see which items are processed.

Fix: Place all continue guards at the top of the loop body, before the main work.

continue Outside a Loop

Effect: Fatal error: 'continue' not in the 'loop' or 'switch' context.

Fix: Only use continue inside loops.


Best Practices

  • Use continue at the top of the loop body to skip items that should not be processed.
  • Give each skip a clear reason (a log message or comment).
  • In while loops, update loop variables before any continue.
  • Use continue 2 to skip an outer item from inside a nested loop or a switch.
  • Prefer array_filter() for simple selection without further processing.

Official reference: https://www.php.net/manual/en/control-structures.continue.php

0 Comments

Reviewed before they appear

No comments yet.

PHP
PHP Home PHP Switch PHP Match Alternative Syntax PHP Loops While Loop Do While Loop For Loop Foreach Loop Nested Loops Break Statement PHP Home PHP Intro PHP Install PHP Built-in Web Server PHP Syntax PHP Tags PHP and HTML PHP Comments PHP Multiline Comments PHP Variables Variables Scope PHP Casting Logical Operators Null Coalescing Operator Spaceship Operator Operator Precedence Continue Statement Modify Strings PHP If...Else...Elseif PHP If Modify Strings PHP If Operators PHP Functions Concatenate Strings PHP If...Else Slicing Strings User-defined Functions Slicing Strings PHP Shorthand if Escape Characters Default Argument Values PHP Nested if Pass by Reference String Interpolation Named Arguments PHP File Upload Variadic Functions Return Values Search in Strings Multibyte Strings Type Declarations in Functions PHP Numbers PHP Math PHP Floats PHP Random Numbers PHP Constants PHP Properties PHP Methods PHP Constructor Constructor Property Promotion PHP Cookies PHP Destructor PHP Access Modifiers Readonly Properties PHP Sessions PHP Inheritance Method Overriding PHP Filters The final Keyword CSRF Protection PHP Filters Advanced Session Security Secure Cookies PHP Magic Constants File Upload Security PHP Callback Functions PHP Operators Filesystem Security PHP JSON Arithmetic Operators Error Reporting in Production Hiding PHP Assignment Operators PHP Configuration (php.ini) Comparison Operators PHP Command Line (CLI) PHP Exceptions Increment / Decrement Operators Migrating to PHP 8 PHP Form Validation PHP Form Required PHP Form URL/E-mail Error Handling Form Input Sanitizing Escaping Output (htmlspecialchars) Custom Error Handler Checkbox, Radio and Select Inputs Sticky Forms PHP Form Complete PHP Date and Time Date Formatting
Ask about this post
AI Ask about this post

Ask questions about Continue Statement and get answers drawn from it.

Signed-in readers only.