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