先日、開発中に、以下と似たようなコードになった。
<?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); ?>
ちょっとした罠だった。