PHP
ポエム

曖昧比較は果たして本当に絶対悪なのか?

はじめに

ポエムです
いちエンジニアの主張です
PHP==曖昧比較と===厳密比較について取り上げます

曖昧比較は果たして本当に絶対悪なのか?

いきなり表題ですが、例えば以下のようなコードを見てください。

if($message == 'hoge'){
  echo('true');
} else {
  echo('false');
}

こんなコードがあった時、僕は間違いなくレビューでこうコメントをつけます

曖昧比較ではなく厳密比較にしてください

これに関しては理由もなく本当に脳死でコメントつけてました
ただ最近ふと「曖昧比較って何のためにあるんだっけ?」となり熟慮したいと思ったのでこの記事を書いてます

曖昧比較のデメリット

そもそも何故曖昧比較はダメなのでしょう?
例えば次のような時がNGです。

$message = 0;
if($message == ''){
  echo('messageは空文字です');
} else {
  echo('messageは'.$message.'です');
}

上記結果は「messageは空文字です」になります(0 == ''がtrue判定になる)
この場合そもそもmessageに数値の0が入ってる時点で変なのですが、空文字判定にヒットしてしまうため意図しない挙動をしてしまう可能性があります

一般的に「意図しない挙動、意図しない判定」をされる可能性が高くなるため、使わない方がよいとされています。

曖昧比較のメリット

私の疑問を掻き立ててしまったコードがこちら

if($icon != ''){
  echo("<i class={$icon}></i>");
}

画面に表示するiconのクラス名を変数に持っており、空文字でなければそのアイコンを表示するというような内容です
このコードをレビューした時のやりとり

私「厳密比較にしてください」
後輩「厳密比較にしたところうまく判定できないところがあったのでこのままにします」
私「うまくいかなかったということは空文字以外があったってこと?」
後輩「はい、NULLが入っている場合がありました。NULLの時に空のiタグが表示されてしまいます」
私「なるほど、ではis_null判定も追加しましょう」
後輩「分かりました!」
で改修したコード

if($icon !== '' && !is_null($icon)){
  echo("<i class={$icon}></i>");
}

空文字でもNULLでもない場合にはiconを表示する
今はこれでも良いですが今後falseや空配列が入ってきた場合(そもそもそうならないようにした方が良いが)に、判定がどんどん複雑化するなーという思いになりました
だったら曖昧比較のままでよいのでは…?🤔

$icon != ''であれば空文字でもNULLでもfalseでも空配列でもやりたいことが実現できる
ここで比較したいのは空文字ではなく「空」であること、だったので厳密に空文字やNULLを比較する必要がなかったのです
ただしそれに気付いたのでこのケースに関しては以下のように修正しました

if( !empty($icon) ){
  echo("<i class={$icon}></i>");
}

結論

やはり原則的にはデメリットの方が多く、厳密に比較した方が堅牢なコードが書けるように思います。
限定的に曖昧比較を使う方がコーディングが楽な場合もありますが

  • 曖昧なので何を比較したいのか書き手と読み手で解釈が異なる可能性がある
  • 読み手の知識が足りない場合に参考にされるコードとしてはやはり相応しくない(コピペで増殖しても困る)

ので、基本的には非推奨という結論になりました。

おわりに

あくまでいち個人、いちエンジニアの主張なので石を投げるのは程々にお願いしますw :sweat: