質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

8回答

860閲覧

PHP 見やすい条件分岐の書き方について

Yasha_Wedyue

総合スコア830

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2020/12/21 22:18

編集2020/12/21 23:47

お世話になります。
表題の件について、色々考えたのですが答えが出ないので質問させてください。

時間帯によって背景色を変えるプログラム(class名を吐き出しCSSで色をつける)を書いているときに、
IF文で書くと非常に見づらくなってしまいました。

そこで、switch文を利用し以下のようにしました。

PHP

1public function get_background_class() { 2 $hour = date("H"); 3 4 if ($hour >= 22) { 5 return "midnight"; 6 } else if ($hour >= 18) { 7 return "night"; 8 } else if ($hour >= 16) { 9 return "evening"; 10 } else if ($hour >= 10) { 11 return "noon"; 12 } else if ($hour >= 7) { 13 return "morning"; 14 } else { 15 return "midnight"; 16 } 17} 18 1920 21public function get_background_class() { 22 $hour = date("H"); 23 24 switch(true) { 25 case $hour >= 22: 26 return "midnight"; 27 case $hour >= 18: 28 return "night"; 29 case $hour >= 16: 30 return "evening"; 31 case $hour >= 10: 32 return "noon"; 33 case $hour >= 7: 34 return "morning"; 35 default: 36 return "midnight"; 37 } 38}

elseのせいでズレていた条件の書かれている場所が、switchの方だときれいに揃い非常に見やすくなったのですが、
この書き方はあまりよろしくないという記事も拝見し(具体的にどう悪いとかは明記されておらず)
であれば、このような連続する条件分岐はどのように書くのが正解なのかと思った次第です。

このあたり個人的な趣味嗜好も絡んでくるでしょうが、こちらのほうがいいよという書き方があれば
参考にさせていただきたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/12/21 22:29

どれくらいの区分があるかにもよります。個人的には3つくらいならifのほうが見やすいですね。
Yasha_Wedyue

2020/12/21 22:39

この時間によっての振り分けは条件が6つありますね。 他にも似たような条件分岐(身長体重からBMIを出しそれを元に"標準体型"や"太り気味"など出力など)も多数あり物によっては6つ以上になると思います。 あまりコード内で記法が変わるのも嫌なので、どこか落とし所をつけてそれに統一したいと思ってます。
m.ts10806

2020/12/21 22:58

回答はしていますが、念のため質問本文にも追記願います。
Yasha_Wedyue

2020/12/21 23:51

後ほどBA決めます。回答ありがとうございます。
guest

回答8

0

この書き方はあまりよろしくないという記事も拝見し(具体的にどう悪いとかは明記されておらず)

switch文はC言語由来、あるいはPascal言語にもcase文という似た構文がありましたが、これらの言語では各caseは互いに異なっている必要がありました。その代わり、caseの比較順序が上から下という制約を置く必要がなく、コンパイラ側は自由に評価順を最適化できました。私の作ったPascalコンパイラでは、状況に応じて、caseの比較をテーブルジャンプあるいは二分探索にしています。
そのような目から見ますと、switchの値が固定で、各caseに比較があり、それを上から下に評価していことに依存したプログラムはあまりよろしくないように見えます。ただし、これは私の極めて主観的な「見え方」であり、他の方にそれを押し付けようとは思いません。

PHPではcaseを上から下に評価する仕様のようです(ただしマニュアルにはそう明記はされていないように思えます)ので、「あまりよろしくない」と評価するのもどうかと思います。ただ、わたくしの胸の中では、こういう書き方は「もやもやする」ものでして、「あまりよろしくない」と書く人の気持ちも理解できます。

私自身は、元々のif ~ else if の列挙は「それほど見にくいとは言えない」というか、極めて明確な構造のように見えますので、リファクタリングを要するほどではないと思いました。

投稿2020/12/22 01:23

ockeghem

総合スコア11701

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yasha_Wedyue

2020/12/22 09:45

なるほど、そういう理由で「あまりよろしくない」だったのですね。
guest

0

ifで良いと思うけど

php

1<?php 2date_default_timezone_set('Asia/Tokyo'); 3$hour = date("H"); 4$css = match(true){ 5 $hour >=22 => 'midnight', 6 $hour >=18 => 'night', 7 $hour >=15 => 'oyatsu', 8 default => 'nai' 9}; 10echo $css;

https://www.php.net/manual/ja/control-structures.match.php

投稿2020/12/21 22:46

hentaiman

総合スコア6426

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yasha_Wedyue

2020/12/21 23:41

これ非常に見やすかったのですがPHP 8からなんですね。見落としてました。 使ってるサーバでPHP 8がまだ使えないので残念ながら使えませんが……。
hentaiman

2020/12/22 01:46

じゃあやっぱりifで良いと思う 他人のソース見る時も変にifとreturn繰り返されるよりはelseifで繋げてある方が一目で一括りの処理だと分かって読み易いし 自分はswtichは一切使いません
guest

0

ベストアンサー

return していくなら

if ($hour >= 22) return "midnight"; if ($hour >= 18) return "night"; if ($hour >= 16) return なんたら; ...

でいいのではないかと

投稿2020/12/21 23:46

y_waiwai

総合スコア87800

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yasha_Wedyue

2020/12/21 23:48

非常に見やすいです。 確かにelse ifである必要性ないですね。
guest

0

提示される変数が int なら配列に全部入れておくのもありっちゃあり。

php

1$arr = [ 2 0 => 'midnight', 3 1 => 'midnight', 45 7 => 'morning', 6 8 => 'morning', 78 23 => 'midnight', 9]; 10 11echo $arr[$hour];

投稿2020/12/21 23:55

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yasha_Wedyue

2020/12/22 09:45

確かに。 ただ、条件6つで24つの配列はもったいない気がしますね。
退会済みユーザー

退会済みユーザー

2020/12/22 11:05

これの良いところは「条件分岐じゃない」ところです。 例えば平日と休日でスケジュールが違う時、条件文の改変なく、配列を入れ替えるだけで対応できます。
guest

0

固定値なのであれば「DBに持つ」もしくは「設定で持つ」という手はなくはないです。

設定(配列)で持った場合。

php

1<?php 2$setting = [ 3 22=>"midnight" 4 ,18=>"night" 5 ,16=>"evening" 6 ,8=>"morning" 7 ,4=>"sunrise" 8]; 9 10$hour = date("H"); 11 12foreach($setting as $n=>$color){ 13 if($hour >= $n){ 14 echo $color; 15 break; 16 } 17}

投稿2020/12/21 22:57

m.ts10806

総合スコア80861

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yasha_Wedyue

2020/12/21 23:48

ちょっと質問の捕らえ方が違いますかね?
m.ts10806

2020/12/22 00:00

どいういうことでしょうか。 現状出されている要件を満たせる書き方をしてみたのですが。
guest

0

PHP

1$ret="morning"; 2if ($hour >= 10) $ret= "noon"; 3if ($hour >= 16) $ret="evening"; 4if ($hour >= 18) $ret="night"; 5if (($hour%22)<=6) $ret="midnight"; 6return ret;

投稿2020/12/22 00:20

yambejp

総合スコア115010

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yasha_Wedyue

2020/12/22 09:44

ifで良さそうですね。
guest

0

質問後半のswitchで良いかと思いますが、見た目が y_waiwaiさんの回答とほとんど変わらないので、このような簡単なケースだと、ifかな。

swtichの問題点は比較が===でなく==なので、例えば""0が等しくなるなど、初心者の想定外の結果となる可能性があります。
が、このケースではtrueと比較式結果との比較なので==で問題ないです。

投稿2020/12/22 00:15

otn

総合スコア84796

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yasha_Wedyue

2020/12/22 09:43

回答ありがとうございます。 ifで良さそうですね。
guest

0

関数にして、早期 return。

投稿2020/12/21 23:03

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yasha_Wedyue

2020/12/21 23:42

はい、関数にして早期 returnしてます。 書き方が悪かったですね、後ほど修正しておきます。
退会済みユーザー

退会済みユーザー

2020/12/21 23:47

ごめん。ちゃんと見てなかった^^; y_waiwai さんのやつで。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問