PHP: switch文の中でcontinueはbreakと同じ

先日、開発中に、以下と似たようなコードになった。

<?php
  // 削除対象IDの配列
  $delete_ids = array();
  foreach($articles as $article){
    switch($mode){
      case 'delete':
        // 削除モード
        switch($article['category']){
          case 'book':
          case 'music':
            // 本と音楽の記事のみ追加
            array_push($delete_ids, $article['id']);
            break;

          default:
            break;
        }
        break;

      default:
        break;
    }
  }
  // 記事を削除する
  $db->delete($delete_ids);

  $insert_articles = array();
  foreach($articles as $article){
    switch($mode){
      case 'delete':
        switch($article['category']){
          case 'book':
          case 'music':
            // 削除済みなので、インサートしないためにcontinue
            continue;
            break;

          default:
            break;
        }
        break;

      default:
        break;
    }
    array_push($insert_articles, $article);
  }
  // 何故か本と音楽のものまでインサートされる!
  $db->insert($insert_articles);
?>

こうしたら、削除したはずの記事まで復活してしまったという感じ。
うーん、ちょっと例を書くのに失敗したなぁ…。摩訶不思議な仕様のやつだったから、オブラートに包みながらソースを再現させるのが難しい…。

まあそれは置いといて、削除対象は無視してcontinueしてるのに、どうもcontinueされてないのは何故だと。調べてみたところ、switch文中のcontinueはbreakと同じらしい。continueを使いたかったら、continue 2を使えだと…。

PHP:switchの中でcontinue from Side-B

だが、switch文のネスト内でcontinue 2をしてみても、駄目だったので(外のswitch文に制御が戻っただけ?)、フラグを使って対応した。

  // 削除は同じ。インサートのみ変更
  $insert_articles = array();
  foreach($articles as $article){
    $book_music_flg = false;
    switch($mode){
      case 'delete':
        switch($article['category']){
          case 'book':
          case 'music':
            $book_music_flg = true;
            break;

          default:
            break;
        }
        break;

      default:
        break;
    }
    if($book_music_flg){
      continue;  // switch文を抜けてからcontinueしたらOK
    }
    array_push($insert_articles, $article);
  }
  $db->insert($insert_articles);
?>

ちょっとした罠だった。


タグ PHP | パーマリンク.

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です