PHPのswitch文で複数の条件分岐を処理する方法をご紹介します。
条件分岐ならif文が一般的ですが、いくつものelse if
が続くような条件分岐だとswitch文が便利です。
ただ、PHP特有のゆるい型変換に苦しめられることもあるでしょう。
そんなswitch文の使い方と、注意点を理解すれば、面倒な条件分岐も簡単に使いこなせるでしょう。
目次
switch文の基本
switc文の使い方
まずは曜日をswitch文で表示させてみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// 変数に Tue を格納 $weeks = 'Tue'; // 条件分岐でTueに該当したら'火曜日'と表示 switch ($weeks) { case 'Mon': echo '月曜日'; break; case 'Tue': echo '火曜日'; break; case 'Wed': echo '水曜日'; break; case 'Thu': echo '木曜日'; break; case 'Fri': echo '金曜日'; break; case 'Sat': echo '土曜日'; break; case 'Sun': echo '日曜日'; break; } |
火曜日
変数に格納されたTue
を元にswitch文で火曜日と表示させましたね。
if文で同じ動作を記述した場合
上記の曜日のサンプルをif文で記述してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// 変数に Tue を格納 $weeks = 'Tue'; // if文でTueに該当したら'火曜日'と表示 if ($weeks == 'Mon') { echo '月曜日'; } else if ($weeks == 'Tue') { echo '火曜日'; } else if ($weeks == 'Wed') { echo '水曜日'; } else if ($weeks == 'Thu') { echo '木曜日'; } else if ($weeks == 'Fri') { echo '金曜日'; } else if ($weeks == 'Sat') { echo '土曜日'; } else if ($weeks == 'Sun') { echo '日曜日'; } |
火曜日
if文だと、else if
が続くイメージですね。
もっと複雑な条件分岐だと記述がゴチャゴチャとなりますが、switch文ならスッキリ記述できます。
switch文の構文
1 2 3 4 5 6 7 |
switch (条件分岐の対象) { case 条件; 処理を記述 break; case…… (条件の数だけ続く) } |
if文では最初のかっこに条件式を記述しますが、switch文では対象だけを記述します。
対象に文字列が含まれていたら、対象より大きかったら、対象と等しいなら…などの条件式は、case
に記述します。
case
任意の処理
break
上記を1セットに、複数のcase
を記述します。
breakは必要?
break
をcase
ごとに付けるのは面倒ですが、もし省いたらどうなるのでしょう?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// 変数に Tue を格納 $weeks = 'Tue'; // break; を省略した switch ($weeks) { case 'Mon': echo '月曜日'; case 'Tue': echo '火曜日'; case 'Wed': echo '水曜日'; case 'Thu': echo '木曜日'; case 'Fri': echo '金曜日'; case 'Sat': echo '土曜日'; case 'Sun': echo '日曜日'; } |
火曜日水曜日木曜日金曜日土曜日日曜日
条件に該当した火曜日
以降が全部表示されてしまいました。
上記のように、switch文は該当したcase
で処理を実行し、次のbreak
かswitch文の最後まで実行し続けてしまいます。
break
の付け忘れに注意しましょう。
switch文のさまざまな使い方
breakを付けずに OR条件での分岐
break
を付けるようご紹介しましたが、break
を付けずに OR条件(論理演算子:いずれかに該当した場合)の分岐もできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// 変数に魚を格納 $fish = 'まぐろ'; // breakまでのcaseいずれかに該当した場合での条件分岐 switch ($fish) { case 'かつお': case 'イワシ': case 'まぐろ': echo '魚です。'; break; case '牛': case '豚': case '鶏': echo '肉です。'; break; } |
魚です。
該当したcase
から、次のbreak
までは処理が実行される性質を利用し、いずれかに該当した場合といった条件分岐もできます。
上記の例では、かつお
イワシ
まぐろ
のいずれかに該当した場合魚です。
と表示させました。
default は else の役目
先ほどの曜日のサンプルで、もし日付などの曜日以外の値が変数に格納されたら、どの曜日にも当てはまりません。
それは困りますね。
if文では、そういった例外的な値はelse
で処理しますが、switch文ではdefault
で処理します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// 変数に日付を格納 $weeks = '2016-02-16'; // どの条件にも当てはまらないので、default が発動 switch ($weeks) { case 'Mon': echo '月曜日'; break; case 'Tue': echo '火曜日'; break; case 'Wed': echo '水曜日'; break; case 'Thu': echo '木曜日'; break; case 'Fri': echo '金曜日'; break; case 'Sat': echo '土曜日'; break; case 'Sun': echo '日曜日'; break; // defaultが発動 default: echo '曜日ではありません。'; } |
曜日ではありません。
どのケースにも当てはまらない場合は、最後にdefault
を付けて処理するとよいでしょう。
比較演算子で「以上、以下」の条件分岐
switch文でもif文同様に、◯◯以上、◯◯以下を表す>
(大なり)、<
(小なり)などの比較演算子を使った条件分岐も可能です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// 年齢を変数に格納 $age = 41; // switch文で年齢を条件分岐 switch ($age) { // 年齢が18歳未満だったら… case $age < 18; echo '18歳未満'; break; // 年齢が18歳〜59歳だったら… case $age >= 18 && $age <= 59; echo '18~59歳'; break; // 年齢が60歳以上だったら… case $age >= 60; echo '60歳以上'; break; } |
19~59歳
参考:比較演算子一覧
switch文の最初のカッコに変数$age
を指定しましたが、case
でも$age < 18
のように比較演算子の左辺で使い、比較演算子で比較しています。
ダブって使っているので冗長なコードになっている感じもしますし、実際switch文でこのようなサンプルコードはなかなか見かけませんね。
一致するかどうか?の複数条件分岐に使いドコロがあるのでしょう。
switch文の型について
switch文は緩やかな比較
switch文は緩やかな比較==
となっており、型まで厳密には比較しません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// 変数にバンド名を格納 $band = '5secondsofsummer'; // switch文で一致するバンドを条件分岐 switch ($band) { // 値が 5 だったら… case 5: echo '5 seconds of summer'; break; // 値が 6 だったら… case 6: echo 'maroon5'; break; // 値が上記以外だったら… default: echo 'そのバンドはありません。'; } |
5 seconds of summer
この結果にはビックリですね!
だって5
と'5secondsofsummer'
が同じ値だと判断されたのですから!
ここがswitch文でもハマる箇所であり、switch文は使わないべきだという論拠となる大きな要因だと思います。
詳しくは下記リンクでご紹介していますが、数字と文字列の変換は、PHPが気を利かせて同じ型で比較しやすいように、文字列を数値に自動変換してしまっているのです。
switch文で厳密に型まで比較
それではswitch文で型まで含めた厳密な比較をするサンプルコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// 変数にバンド名を格納 $band = '5secondsofsummer'; // switch文にまず true を指定 switch (true) { // === で型まで厳密に比較 case ($band === 5): echo '5 seconds of summer'; break; case ($band === 6): echo 'maroon5'; break; default: echo 'そのバンドはありません。'; } |
そのバンドはありません。
ようやく思うような結果が得られましたね。
上記サンプルでは、通常のswitch文とは逆になっています。
- switch文の最初のカッコ内に、本来
case
で指定する条件が入る case
には、本来switch文の最初のカッコ内に入るべき条件式が入る
そして、以下のように動作しています。
- もし、変数
$band
の値と5
がtrue
だったら…
厳密比較は以下がポイントです。
- switch文の最初のカッコ内に
true
と書く case
で===
を使って型まで厳密に比較する
HTML埋め込みでもスッキリ記述?
PHPはHTMLに埋め込んで記述する場合も多いものですが、ソースが汚くなりますね。
そんなときは、endswitch
を使うと、スッキリ?書くことができますよ。
(好みの問題だとは思いますが…)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// 変数に都市名(川崎)を格納 <?php $city = 'kawasaki'; ?> <p> // switch( )と最初の case の間は空白を含めた何かを出力するとエラーになる <?php switch ($city) : ?> <?php case ('yokohama') : ?>横浜<?php break; ?> <?php case ('kawasaki') : ?>川崎<?php break; ?> <?php case ('yokosuka') : ?>横須賀<?php break; ?> // endswitch を最後に付ける <?php endswitch; ?> </p> |
川崎
if文などでもよく使う書き方ですが、switch文では以下の点を注意しましょう。
- switch文と最初の
case
の間で、空白を含む何かを出力すると構文エラーになる - 最後に
endswitch
を付ける
HTMLタグの間にピンポイントにPHPを挿入するなど、(好みの問題だとは思いますが)スッキリ記述できるのではと思います。
以上、switch文を見てきましたが、型の比較に注意すれば便利に使えますね。
しかも、if文に比べても処理が速い可能性があるとマニュアルに記載されています。
switch文では、条件は1度だけ評価され、 その結果が各case文と比較されます。 elseif文では、条件は、再度評価されます。 使用する条件が単純な比較処理よりも複雑な処理を行ったり、 重い繰り返し処理を行う場合、switchの方が より処理が速い可能性があります。
switch文に限らず、PHPは型を意識せずコーディングができますが、それにより思わぬ誤動作を起こしたりします。
型を意識したコーディングを心がけたいものですね。