SE_BOKUのまとめノート的ブログ

SE_BOKUが知ってること・勉強したこと・考えたことetc

PHPでよく見かけたcontinueの使い方間違い

目次

PHPでよく見かけたcontinueの使い方間違い

PHPのシステムのトラブル対応時に、よく見かける「バグ」のパターンがあります。

そのひとつが「continue」の使い方の勘違いです。

 

for文などで使う普通のcontinue

continueを使うシーンは、以下のようにforなどの繰り返しの中で、条件によって後続処理をスキップして繰り返しの頭に戻りたいときが、ほとんどです。

for ($i = 0; $i <= 5; $i++) {
    if ($i == 3) {
        continue;
    }
    print($i . "です");
}

 

実際、上記を実行すると、3の時に「 print($i . "です");」の部分がスキップされて、以下のような出力になります。

0です
1です
2です
4です
5です

 

間違うのはforの中にswitch構文がある場合

僕がよく見かける間違いは、for文にSwitch構文がある以下のパターンです。

for ($i = 0; $i <= 5; $i++) {
    switch ($i) {
        case 3:
            continue;
        default:
            print($i . "です");
            break;
    }
    print("!!");
}

 

意図はわかります。

if文でなく、switch構文で処理して、値が「3」の時は、後続をスキップしてfor文のあたまにもどりたい・・ようするに、前の例と同じことがしない・・のでしょう。

でも。

処理結果は以下のようになります。

Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in C:\00boku\webwork\index.php on line 11
0です!!
1です!!
2です!!
!!
4です!!
5です!!

なお、PHP8で動かしたときは、switch構文の中でcontinueを書くと上記のようなWarningがでますが、処理は継続されるので、結果を確認します。

!!だけが表示されているので、後続処理がスキップされていないのがわかります。

switch構文の中の「continue」は「break」と等価なので、当然の結果なのですけど記述量が多くて1画面内に全体がおさまってない場合とかだと、うっかり、continueでforの頭に戻すつもりで使ってて、それが「バグ」になってるという、このパターンを割とよく見かけます。

 

正しい書き方は「continue 2」とかだったりする

上記のような場合で正しい書き方は以下のように「continue 2」とします。

for ($i = 0; $i <= 5; $i++) {
    switch ($i) {
        case 3:
            continue 2;
        default:
            print($i . "です");
            break;
    }
    print("!!");
}

 

こうすると、意図したとおりの結果(最初の例と同じ)になります。

0です!!
1です!!
2です!!
4です!!
5です!!

 

PHPではswitch構文はループとみなされるのです

結果は納得できても、なんかややこしい感じは否めません。

なぜ、こんなことになるのかの理由はPHPのマニュアルに明記されています。

注意: PHP では、continue の動作に関しては switch 文がループ構造とみなされます。 continue に引数を渡さなかった場合の動きは break と同じですが、間違いの元なので警告が生成されます。 switch がループ内にある場合、 continue 2 とすると、外側のループの次回の処理から続行します。

www.php.net

そう。

continue の動作に関しては switch 文がループ構造とみなされます

これが原因です。

これは言語仕様なので、そういうもんだと理解して、勘違いのバグをうめこまないように注意しましょう.

ということで。

ではでは。