PHP 入門

PHP break と continue

breakcontinue ステートメントは、ループの実行フローに対してパーティクルレベル(精密)なコントロールを提供します。ループの本来の目的は、外部条件が満たされるまでイテレーションを繰り返すことですが、これら2つのキーワードを使用することで、実行時の内部ロジックに基づいてループ体内部から直接そのライフサイクルを変更することが可能になります。

1. break ステートメント (ループの完全終了)

break ステートメントは、現在のループの実行を即座に終了させます。コードがこのキーワードに遭遇すると、PHP インタープリタはループブロック内の残りのコードをすべて無視し、ループを「脱出(エスケープ)」して、ループの外部にある次のステートメントを実行します。

ユースケース: コレクション内から特定のアイテムを検索し、それが見つかった直後に検索を停止したい場合や、特定の例外が発生してイテレーションを継続できなくなった場合に、break を使用するのが最適です。

<?php
$products = [
    ['id' => 1, 'name' => 'ノートパソコン', 'in_stock' => true],
    ['id' => 2, 'name' => 'タブレット', 'in_stock' => false],
    ['id' => 3, 'name' => 'スマートフォン', 'in_stock' => true],
];

foreach ($products as $product) {
    if (!$product['in_stock']) {
        echo "在庫切れの商品を発見:" . $product['name'] . "。処理を停止します。\n";
        break; // foreach ループ全体を即座に脱出
    }
    echo "処理中: " . $product['name'] . "... 完了。\n";
}

// break の後、コードはここから実行を継続します
?>

上記の例では、ループは2回目のイテレーションで終了します。3番目の商品(スマートフォン)は在庫があるにもかかわらず、処理されることはありません。

2. continue ステートメント (現在のイテレーションをスキップ)

continue ステートメントは、現在のイテレーションの残りのコードをスキップし、ループの条件チェック箇所まで直接ジャンプして、次のイテレーションを開始します。break とは異なり、ループ全体を終了させるわけではなく、「今回の周(サイクル)」の実行を中止するだけです。

ユースケース: データをフィルタリングする必要がある場合(例:無効な入力や処理不要なレコードをスキップする際)に、continue が威力を発揮します。

<?php
$transactions = [150.00, -20.00, 300.00, -5.00, 50.00];

foreach ($transactions as $amount) {
    // 正の数のトランザクション(収入)のみを処理
    if ($amount <= 0) {
        continue; // 今回のループの残りをスキップし、次の $amount へ進む
    }
    
    echo "有効な取引を処理中:$" . $amount . "\n";
}
?>

ここでは、負の値に遭遇するとコードはそれを無視し、アレイ内の次の要素の処理へ進みます。これにより、出力には有効な収入取引のみが含まれるようになります。

3. 実行フローの比較

これら2つのキーワードの根本的な違いは、ステートメント実行後にコントロールフロー(実行権限)がどこへ向かうかにあります。

  • break に遭遇: 「緊急停止」ボタンを押すことに相当します。ループは即座に終了し、プログラムはループの外へ移動します。
  • continue に遭遇: 「早送り」ボタンを押すことに相当します。目の前の処理を飛ばして、次のループチャレンジを即座に開始します。

4. ネストされたループの制御 (マルチレベル脱出)

コード内でネストされたループ(ループの中に別のループが入っている構造)を使用している場合、デフォルトでは breakcontinue はそれらを含んでいる最も内側のループに対してのみ作用します。

外側のループまで影響を与えたい場合は、キーワードの後に数字のパラメータを指定する必要があります。これは、脱出したい階層の数を表します。

<?php
$categories = ['電子機器', '衣類'];
$items = [1, 2, 3];

foreach ($categories as $cat) { // 外側ループ (レベル 2)
    foreach ($items as $item) { // 内側ループ (レベル 1)
        if ($cat === '電子機器' && $item === 2) {
            // 内側と外側の両方のループを同時に脱出
            break 2; 
        }
        echo "カテゴリ:$cat,アイテム:$item\n";
    }
}

// break 2 によって直接ここへジャンプします
?>

この例では、break 2 が内側の foreach ($items) と外側の foreach ($categories) ループを同時に終了させ、ネスト構造全体の実行を即座に停止させています。