【PHPでハマった・失敗した話 #1】基本構文(foreach・switch)で陥った落とし穴

PHP, ハマった, 失敗した, 基本構文, foreach, switch 未分類
この記事は約4分で読めます。
スポンサーリンク

どうも、ITエンジニアな隣の鈴木(@next_suzuki)です。

【PHPでハマった・失敗した話】シリーズの第一弾です。
基本構文(foreach・switch)で陥った落とし穴 について語ります。

概要

PHPの基礎構文「foreach」と「switch」を組合せたプログラムを記述したら、バグ・不具合を含んだソースを生み出してしまった。

事象

ループ処理を組み込んだAPIを作成して、フロント側で表示させたら、意図した結果が得られずバグが発生。
原因は何だ?!

問題のコード

下記が問題のプログラム・ソース。

$total = 0;
$numberArray = [1, 2, 3, 4];
foreach($numberArray as $number){
    switch($number){
    case 3:
        continue; // ここでforeachを抜けるはずが、処理が継続された。
    default:
        break;
    }
    $total += $number; // $numberが"3"のときも加算されてしまう
}

結論

continue の使い方が謝っていた。

解決方法

PHPのお作法として、switch文で外のループを抜ける際は外ループを指定する必要があるらしい。
よって、外ループを指定するために continue 2 と記述すべきだった。

正常なコード

$total = 0;
$numberArray = [1, 2, 3];
foreach($numberArray as $number){
    switch($number){
    case 3:
        continue 2; // 外側のループ(foreach)に戻ります。
    default:
        break;
    }
    $total += $number;
}

振り返り

ハマった・失敗した時に抱いた感情・学び。

情けない

プログラムを書くようになって10年以上が経過した。
もう10年もプログラムを書いているのに、こんな初歩的なミスで失敗するのか…。とショックだった。
PHPの経験が浅いとはいえ、こんなことも知らない自分が情けなかった。

C系の言語と違うのか

僕は元々はC++などのC系が専門なので、この基本構文のことを知らなかった。
C++だとbreakでループを抜けて次のイテレーションへ進む。

PHPはC言語を元に作成されているはずなので、同じ挙動になるか思っていたけど違った…。

continueの数値指定

失敗したおかげで学んだわけだが、PHPはcontinueで数字を指定すれば外ループまで抜けることが可能らしい。
例えば多重ループの時に、内側のループにいる時に、外側のループを数字で指定すれば、外まで処理が抜けてくれる。

$total = 0;
$loopArrayOne = [a, b, c];
$loopArrayTwo = [1, 2, 3];
foreach($loopArrayOne as $number){   // continue 3の場合に戻る位置
    foreach($loopArrayTwo as $number){ // continue 2の場合に戻る位置
        switch($number){
        case 3:
            continue 3; // 外側のループ(loopArrayOne)に戻ります。
        default:
            break;
        }
        $total += $number;
    }
}

まあC++でもgoto文が存在するが、あまり使用するべきではない。
C++で多重ループから抜ける場合、if文でフラグを使用してループから抜けていたが、if文が大量に発生して可読性が落ちて嫌だった。

しかし、PHPだとcontinueが使用できるので、コードが煩雑にならなくて便利だな。とは思った。
(もしかしたらPHPエンジニア界隈ではC++のgoto文みたいにご法度なお作法かもしれないけど…)

match

switch文の代わりに、match式という構文が存在するらしい。
存在を知らなかったので学べてラッキーだった。

おわり

ハマった・失敗した時は、「こんなことも知らないのか」と情けなくて落ち込んだ。
しかし、プログラミングでハマる・失敗なんて、だいたいこんなお作法系なのである。
新しい言語が開発されて学ぶたびに、ぶち当たる問題なのだ。
新しい知識に挑戦している結果なのだから、前向きにとらえて、経験を積み重ねていきたいと思う。

タイトルとURLをコピーしました