先日、開発中に、以下と似たようなコードになった。
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | <?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文に制御が戻っただけ?)、フラグを使って対応した。
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | // 削除は同じ。インサートのみ変更 $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 ); ?> |
ちょっとした罠だった。