==は、PHPが2つの値を共通の型に変換したあとで等しいかどうかを調べます。===は、等しいうえに型も同じかを調べます。そのため1 == "1"はtrueですが、1 === "1"はfalseです。
比較にまつわるバグのほとんどは、==が予想外のものを変換することから生まれます。===と!==を基本にして、変換が欲しいとわかっているときだけ==に切り替えるのがよいでしょう。
PHPの比較演算子の一覧
| 演算子 | 名前 | trueになる条件 |
|---|---|---|
$a == $b | 等しい | 型の自動変換後に等しい |
$a === $b | 同一 | 等しく、型も同じ |
$a != $b, $a <> $b | 等しくない | 型の自動変換後に等しくない |
$a !== $b | 同一でない | 等しくない、または型が違う |
$a < $b, $a > $b | より小さい、より大きい | |
$a <= $b, $a >= $b | 以下、以上 | |
$a <=> $b | 宇宙船 | -1、0、1のいずれかを返す |
ゆるい比較と厳密な比較の表
この表のすべてのセルはPHP 8.3で計算したものです。==と===を切り替え、セルをタップすると式が表示されます。==の表はnull、""、"0"、[]の行が意外な結果だらけで、===の表は対角線だけです。
| $a == $b | true | false | 1 | 0 | -1 | "1" | "0" | "" | null | [] | "php" | "10" | "1e1" |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| true | |||||||||||||
| false | |||||||||||||
| 1 | |||||||||||||
| 0 | |||||||||||||
| -1 | |||||||||||||
| "1" | |||||||||||||
| "0" | |||||||||||||
| "" | |||||||||||||
| null | |||||||||||||
| [] | |||||||||||||
| "php" | |||||||||||||
| "10" | |||||||||||||
| "1e1" |
==は異なる型をどう比較するか
PHP 8が従うルールを、実際に効いてくる順に並べます。
- 数値の文字列どうしは数値として比較されます:
"10" == "1e1"も"1" == "01"もtrueです。 - 数値と数値の文字列では、文字列が数値になります。
100 == "1e2"はtrueです。 - 数値と数値でない文字列では、PHP 8以降は数値が文字列になり、文字列として比較されます。
0 == "a"はfalseです(PHP 7ではtrueでした)。 - 任意の値とboolでは、両辺がboolに変換されます。
"a" == trueと[] == falseはtrueです。 - nullと文字列では、
nullが""になるので、null == ""はtrueですがnull == "0"はfalseです。それ以外の型に対しては、nullはfalseとして比較されます。 - 配列どうしは、同じキーと値のペアを持つとき等しくなります。
最後の行は、nullとの大小比較がほとんど意味を持たない理由を示しています。nullはfalseに、-1はtrueになり、false < trueだからです。
等しくない:!=と!==
!=と<>は同じ演算子です。!==はその厳密版です。違いがいちばん問題になるのは、strposのように0かfalseを返す関数です。
0はfalseに変換されるので、0 != falseはfalseです。intはboolではないので、0 !== falseはtrueです。同じ罠はarray_searchと、strictフラグなしのin_arrayにもあります。
文字列を比較する
<と>は文字列をバイト単位で比較します(単純なASCIIならアルファベット順)。両方の文字列が数値なら、数値として比較されます。大文字小文字を区別しない比較や「自然な」順序には関数を使います。
宇宙船演算子<=>
$a <=> $bは、$aが小さければ-1、等しければ0、大きければ1を返します。<や==と同じルールを使い、ソートのコールバックを書くいちばん短い方法です。
2つの配列を<=>で比較すると要素ごとに比較されるので、このコールバックはまず年齢で、次に名前で並べ替えます。ほかの並べ替えの方法は配列のソートのページにあります。
よくあるミス:floatを==で比較する
floatは2進数で保存されるので、多くの10進数の値は近似値です。0.1 + 0.2はぴったり0.3ではなく、==はその差を見分けます。
金額はセント単位の整数で保存し、それを===で比較しましょう。
よくある質問
PHPの==と===の違いは何ですか?
==は両辺を共通の型に変換してから比較するので、1 == "1"はtrueです。===は値が等しく型も同じときだけtrueなので、1 === "1"はfalseです。変換させたいのでなければ===を使いましょう。
PHPで0 == "a"はtrueですか?
PHP 8からはtrueではありません。数値と数値でない文字列を比較すると、PHP 8は文字列として比較するので、0 == "a"はfalseです。PHP 7では文字列が0にキャストされ、結果はtrueでした。
PHPの!=と!==の違いは何ですか?
!=(別名<>)は==の反対で、型を変換したあとの値が等しければfalseです。!==は===の反対で、値か型が違えばtrueです。そのため0 !== falseはtrueですが、0 != falseはfalseです。
PHPで2つのfloatを比較するには?
floatの計算結果に==を使ってはいけません:0.1 + 0.2 == 0.3はfalseです。代わりに差を小さな許容値と比べるか(abs($a - $b) < PHP_FLOAT_EPSILON)、両方を必要な精度に丸めます。