## 比較演算子

比較演算子は、その名前が示すように、二つの値を比較します。 型の比較表 に、型に関連するさまざまな比較の例があります。

比較演算子
例 | 名前 | 結果
--- | --- | ---
$a == $b | 等しい | 型の相互変換をした後で $a が $b に等しい時に `TRUE`。
$a === $b | 等しい | $a が $b に等しく、および同じ型である場合に `TRUE` 。
$a != $b | 等しくない | 型の相互変換をした後で $a が $b に等しくない場合に `TRUE`。
$a <> $b | 等しくない | 型の相互変換をした後で $a が $b に等しくない場合に `TRUE`。
$a !== $b | 等しくない | $a が $b と等しくないか、同じ型でない場合に `TRUE` 。
$a < $b | より少ない | $a が $b より少ない時に `TRUE`。
$a > $b | より多い | $a が $b より多い時に `TRUE`。
$a <= $b | より少ないか等しい | $a が $b より少ないか等しい時に `TRUE`。
$a >= $b | より多いか等しい | $a が $b より多いか等しい時に `TRUE`。
$a <=> $b | 宇宙船 | $a が $b より小さいときに負の値、 $b と等しいときに 0、 $b より大きいときに正の値。 PHP 7 以降で使用可能。

整数値を文字列と比較したり、比較に数値形式の文字が含まれる場合は、文字列が 数値に変換され、 数値としての比較を行います。これらのルールは、 switch 文にも適用されます。 === あるいは !== による比較では型変換は発生しません。 この場合は値だけでなく型も比較します。

`<?php
var_dump(0 == "a"); // 0 == 0 -> true
var_dump("1" == "01"); // 1 == 1 -> true
var_dump("10" == "1e1"); // 10 == 10 -> true
var_dump(100 == "1e2"); // 100 == 100 -> true
switch ("a") {
case 0:
echo "0";
break;
case "a": // "a" は 0 にマッチするので、決してここにはたどりつきません
echo "a";
break;
}
?>`
`<?php
// Integer
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
// Float
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
// 文字列
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
echo "a" <=> "aa"; // -1
echo "zz" <=> "aa"; // 1
// 配列
echo [] <=> []; // 0
echo [1, 2, 3] <=> [1, 2, 3]; // 0
echo [1, 2, 3] <=> []; // 1
echo [1, 2, 3] <=> [1, 2, 1]; // 1
echo [1, 2, 3] <=> [1, 2, 4]; // -1
// オブジェクト
$a = (object) ["a" => "b"];
$b = (object) ["a" => "b"];
echo $a <=> $b; // 0
$a = (object) ["a" => "b"];
$b = (object) ["a" => "c"];
echo $a <=> $b; // -1
$a = (object) ["a" => "c"];
$b = (object) ["a" => "b"];
echo $a <=> $b; // 1
// 値だけを比較します
$a = (object) ["a" => "b"];
$b = (object) ["b" => "b"];
echo $a <=> $b; // 1
?>`

多くの型では、以下の表にしたがって（上から順に）比較が行われます。

さまざまな型の比較
第 1 オペランドの型 | 第 2 オペランドの型 | 結果
--- | --- | ---
null または string | string | `NULL` を "" に変換し、数値または文字として比較します
bool または null | あらゆる型 | 両辺を bool に変換し、`FALSE` < `TRUE` と判断します
object | object | 組み込みクラスには独自の比較基準が定義されています。それ以外の クラスは比較できません。同じクラスであるかどうかは - プロパティが 同じ値であるかどうかを配列形式で比較（PHP 4）、PHP 5 では ここで説明されています。
string, resource または number | string, resource または number | 文字列やリソースを数値に変換し、算術演算を行います
array | array | 要素数の少ない配列のほうが小さくなります。オペランド 1 のキーが オペランド 2 に存在しない場合、配列は比較できません。そうでない場合は 個々の要素の値を比較します（以下の例を参照ください）
object | あらゆる型 | object のほうが常に大きくなります
array | あらゆる型 | array のほうが常に大きくなります

例1 Boolean/null comparison

`<?php
// Bool and null are compared as bool always
var_dump(1 == TRUE); // TRUE - same as (bool)1 == TRUE
var_dump(0 == FALSE); // TRUE - same as (bool)0 == FALSE
var_dump(100 < TRUE); // FALSE - same as (bool)100 < TRUE
var_dump(-10 < FALSE);// FALSE - same as (bool)-10 < FALSE
var_dump(min(-100, -10, NULL, 10, 100)); // NULL - (bool)NULL < (bool)-100 is FALSE < TRUE
?>`

例2 一般的な配列の比較

`<?php
// 標準の比較演算子を用いて、配列はこのように比較されます
function standard_array_compare($op1, $op2)
{
if (count($op1) < count($op2)) {
return -1; // $op1 < $op2
} elseif (count($op1) > count($op2)) {
return 1; // $op1 > $op2
}
foreach ($op1 as $key => $val) {
if (!array_key_exists($key, $op2)) {
return null; // uncomparable
} elseif ($val < $op2[$key]) {
return -1;
} elseif ($val > $op2[$key]) {
return 1;
}
}
return 0; // $op1 == $op2
}
?>`

strcasecmp(), strcmp()、 配列演算子, マニュアルの 型 のセクションも参照してください。

警告

# 浮動小数点数値の比較

ふたつの float 値が等しいかどうかを調べてはいけません。 float の内部的な表現方法がその理由です。

詳細な情報は float のドキュメントを参照ください。

### 三項演算子

もうひとつの条件演算子として "?:"（あるいは三項）演算子があります。

例3 デフォルト値を設定する

`<?php
// 三項演算子の使用例
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
// 上記は以下の if/else 式と同じです。
if (empty($_POST['action'])) {
$action = 'default';
} else {
$action = $_POST['action'];
}
?>`
(expr1) ? (expr2) : (expr3) という式は、式1 が `TRUE` の場合に 式2 を、 式1 が `FALSE` の場合に 式3 を値とします。

PHP 5.3 以降では、三項演算子のまんなかの部分をなくすこともできるようになりました。 式 expr1 ?: expr3 の結果は、expr1 が `TRUE` と同等の場合は expr1、 それ以外の場合は expr3 となります。

> 注意: 三項演算子は式であり、値としては評価されずに式の結果として評価される ことに注意してください。演算結果をリファレンスとして返したい場合に、 これを知っておくことが大切です。結果をリファレンスとして返す関数で return $var == 42 ? $a : $b; とすることはできず、 警告が発生します。

> 注意:

> 三項演算子を "積み重ねて" 使用することは避けましょう。 ひとつの文の中で複数の三項演算子を使用した際の PHP の振る舞いは、 少々わかりにくいものです。

> 例4 三項演算子のわかりにくい挙動

> `<?php
> // ぱっと見た感じでは、これは 'true' と表示されると思うでしょう。
> echo (true?'true':false?'t':'f');
> // しかし、実際には上の出力結果は 't' です。
> // なぜなら、三項演算子は左から右へ順に評価されるからです。
> // 上のコードをもう少しわかりやすく書くと、このようになります。
> echo ((true ? 'true' : false) ? 't' : 'f');
> // まず、最初の式が 'true' と評価されます。この 'true' は
> // (bool)true と評価されるので、それをもとに二番目の三項
> // 演算子が評価されます。
> ?>`

### Null 合体演算子

PHP 7 以降ではさらに、"??" 演算子 (null 合体演算子) が使えるようになりました。

例5 デフォルト値の代入

`<?php
// Null 合体演算子の使用例
$action = $_POST['action'] ?? 'default';
// 上の文は、この if/else 文と同じ意味です
if (isset($_POST['action'])) {
$action = $_POST['action'];
} else {
$action = 'default';
}
?>`
式 (expr1) ?? (expr2) は、 expr1 が `NULL` である場合は expr2 と評価され、それ以外の場合は expr1 と評価されます。

この演算子は、左側の値が存在しない場合でも notice が発生しません。 isset() と同じ挙動です。 これは、配列のキーを扱う場合に便利です。

> 注意: Null 合体演算子は式であることに注意しましょう。変数として評価されるのではなく、式の結果として評価されます。 変数を参照で返そうとするときには、これを意識しておくことが重要です。 参照返しの関数で return $foo ?? $bar; のように書いてもうまく動かずに、 警告が発生します。

> 注意:

> Null 合体演算子はネストさせることもできます。

> 例6 Null 合体演算子のネスト

> `<?php
> $foo = null;
> $bar = null;
> $baz = 1;
> $qux = 2;
> echo $foo ?? $bar ?? $baz ?? $qux; // 出力は 1 です
> ?>`