【PHP】比較演算子を使うときは厳密比較をした方がいい理由

エディタPHP

こんにちは。いっとくです!

突然ですが自分と他人と比べて劣等感を抱くことありませんか?

そんなときは心の比較演算子を外すことをオススメします。ありのままのあなたが素敵です。

なんつって!!これ以上うざいこと言わないから閉じないでー!!

さてさて、今日もPHP道を極めるべくアウトプットしていきます。

本日は比較演算子で厳密比較をするか曖昧比較をするかというお話。

スポンサーリンク

比較演算子を使うときは厳密比較を使うべき理由

PHPにおいて両辺の値が等しいか調べるために使える比較演算子は==と===があります。

==は曖昧比較と呼ばれ、型が違ってもある程度いい感じに比較をしてくれ、===は厳密比較と呼ばれ、型まで同じじゃないとすぐさまfalseを返す偏屈者です。

プログラミングの勉強を始めたばかりの頃の僕は、型云々でfalseを返されるのが嫌だったので、==や!=などの曖昧な比較演算子を使ったゆるフワ比較大好き人間でした。

しかし、PHPの良書でもあるパーフェクトPHPには基本的には常に===や!==を使って厳密比較をすべきと書いてあるし、一般的にも厳密比較を使うべしと言われているので、実際に現場で働いてからは可能な限り厳密比較を使うようにしていたんですね。

そこで、ふと疑問が湧いてきました。

厳密比較を使うことにはどんなメリットがあるのだろうか?

結論を言ってしまうと、曖昧な比較だと渡された値によっては予想外の動きをするのでバグの原因になるということなのですが、それらが実際にコードでどんな動きをするのかをみていきたいと思います。

厳密比較と曖昧比較の挙動の違い

まずは、こんな動きから

<?php

var_dump((1 == 1)); //true
var_dump((1 == '1')); //true
var_dump((1 == true)); //true
var_dump((1 == array(1))); //false
var_dump((1 == null)); //false

==による比較では、型の比較をしないので、文字列型でも数値型でもtrueになります。ここで気をつけるべきはtrueと比較した時も等しいと見なされる点。

曖昧比較だと、0以外の数字はtrueと等しいという結果が返ってきます。

うん、結構曖昧だね〜。

これが厳密比較だとこんな感じに

<?php

var_dump((1 === 1)); //true
var_dump((1 === '1')); //false
var_dump((1 === true)); //false
var_dump((1 === array(1))); //false
var_dump((1 === null)); //false

超わかりやすい。シンプル。これならまず予想外の動きはしない。

でも、DBから取得した値ってDB上ではintでも文字列型にキャストされてたりするので、厳密比較の場合だといちいちキャストしないといけないというデメリットもある。

なので面倒臭いな〜って思うこともあるのですが、次の挙動を知った時、僕は曖昧比較の圧倒的曖昧さに衝撃を受け、なるべく使いたくねー!と思うようになりました。

<?php

var_dump((1 == '1ああああ')); //true
var_dump((1 === '1ああああ')); //false

まじか!!「ああああ」の部分が完全に無視されてます。

僕も28年の人生でここまで盛大な無視に出会ったことはありません。

文字列の先頭が数字だった場合、数字の部分だけ自動でキャストされて比較されるわけだから、たまたま先頭が数字のテキストが入ったら変な動きする可能性があるってことでしょ。…こえええ〜

そして0との比較だと上の例に追加して、空文字やnullでもこんな動きをかましてきます。

<?php

var_dump((0 == '')); //true
var_dump((0 == null)); //true

ひいいぃぃ!

0 == ‘0’ == ” == false == nullー!!

恐ろしい。

それらを等しいと分類する気持ちはわからなくもないんですが…等しいってなんですか??

実際のコードでは条件分岐で変数と比較演算子を混ぜて使うことが結構あると思います。

<?php

if ($a === $b) {
    // 処理処理処理ー!
} elseif ($a === $c) {
    // 処理処理処理ー!
}

そして、もし変数の中にユーザーが入力した値を使っている場合だと、自分が予想もしていなかった値が入ってくることがあります。

そんなコードの中で曖昧比較をしていた場合、この柔軟性という思いやりせいで予想外の分岐をし、動いて欲しくない処理が動いてしまったり(最悪の場合セキュリティに関わることとか…)するなどデメリットはかなり大きい。

それに対して厳密比較をしておけば、予想外の値が入ってきた場合にエラーで処理を止めることができます。

さらにチームで開発している場合、自分が書いていない部分のコードって値に何が入って何を返すかがはっきりとわかった方が、読み取りやすいというメリットもあります。

曖昧比較は、型を意識することなく使えるので便利だし、意外とそのまま書いても不具合に遭遇する確率が高いというわけじゃないのですが、常に型を意識して書いた方が、何がダメでエラー出てるとかもわかりやすいはず。

ただ既存のプロジェクトに途中から参加して、その辺のルールが曖昧になってるコードに出会うと、厳密比較にすることによって途方もないくらいエラーが出たり、修正範囲がめちゃくちゃ広くなってしまうこともあります。

そんなわけで、既存コードの兼ね合いでどうしても曖昧比較じゃないとエラーが出続けるという場合は納期とかもあると思うのでバランスを見ながらも、基本的には厳密比較で書いていくというのが一番安全で堅実な方法という結論に至りました。

特にPHPの勉強を始めたばかりの初心者の方は、厳密比較うぜ〜って思う人が多いと思うのですが、結局続けていくと厳密比較の方がいいなって思う時が来るはずなので、癖をつけるためにも意識しておいたほうがいいかなと思います!

以上、いっとくでした!さいなら!

コメント

タイトルとURLをコピーしました