比較演算子(== / === / != / <=> ...)
値の一致・大小を調べるには比較演算子を使用します。『PHP』には型変換を伴うゆるい比較(『==』)と型変換を行わない厳密比較(『===』)があり、どちらを選ぶかによって挙動が大きく異なります。
比較演算子一覧
| 演算子 | 名称 | 概要 |
|---|---|---|
| == | 等値(ゆるい比較) | 型変換を行ったうえで値が等しければ『true』を返します。 |
| === | 厳密等値 | 型変換を行わず、値と型が両方一致する場合に『true』を返します。 |
| != | 不等値(ゆるい比較) | 型変換を行ったうえで値が等しくなければ『true』を返します。『<>』と同義です。 |
| <> | 不等値(ゆるい比較) | 『!=』と同義です。古いコードで見かけることがありますが、現在は『!=』を使うのが一般的です。 |
| !== | 厳密不等値 | 型変換を行わず、値または型が異なる場合に『true』を返します。 |
| < | より小さい | 左辺が右辺より小さい場合に『true』を返します。 |
| > | より大きい | 左辺が右辺より大きい場合に『true』を返します。 |
| <= | 以下 | 左辺が右辺以下の場合に『true』を返します。 |
| >= | 以上 | 左辺が右辺以上の場合に『true』を返します。 |
| <=> | 宇宙船演算子 | 左辺が右辺より小さければ『-1』、等しければ『0』、大きければ『1』を返します。 |
== と === の違い
『==』は比較前に型変換(型強制)を行います。一方、『===』は型変換を一切行わず、値と型の両方が一致する場合のみ『true』を返します。型の異なる値を比較する際に意図しない結果が生じやすいため、原則として『===』を使用することを推奨します。
| 比較式 | ==(ゆるい) | ===(厳密) | 理由 |
|---|---|---|---|
| 0 == false | true | false | falseは整数に変換されると0になります。 |
| 0 == "" | true | false | 空文字列は数値に変換されると0になります(PHP 7まで)。PHP 8以降はfalseになります。 |
| 0 == "0" | true | false | 文字列"0"は数値に変換されると0になります。 |
| "1" == 1 | true | false | 文字列"1"は数値に変換されると1になります。 |
| null == false | true | false | nullとfalseはゆるい比較では等しいと見なされます。 |
| null == 0 | true | false | nullは数値に変換されると0になります。 |
| null == "" | true | false | nullは文字列に変換されると空文字列になります。 |
| "" == false | true | false | 空文字列はboolに変換されるとfalseになります。 |
| 1 === 1 | true | true | 値も型も一致するため両方trueになります。 |
| "abc" === "abc" | true | true | 値も型も一致するため両方trueになります。 |
宇宙船演算子(<=>)
宇宙船演算子(『<=>』)はPHP 7で導入されました。左辺が右辺より小さければ『-1』、等しければ『0』、大きければ『1』を返します。主に独自ソートのコールバック関数(『usort()』など)の記述に使用します。
| 式 | 戻り値 | 意味 |
|---|---|---|
| $a <=> $b が -1 | -1 | $a が $b より小さいです。 |
| $a <=> $b が 0 | 0 | $a と $b は等しいです。 |
| $a <=> $b が 1 | 1 | $a が $b より大きいです。 |
厳密比較を推奨する理由と実務での注意点
PHPでは、フォームやURLパラメータから受け取った値は常に文字列型です。この文字列をゆるい比較で整数と照合すると型変換が発生し、意図しない結果になることがあります。
| 場面 | 推奨 | 理由 |
|---|---|---|
| 値の同一性チェック全般 | === | 型と値の両方を確認できるため予測しやすい挙動になります。 |
| フォーム入力との比較 | 明示的にキャストしてから === | フォームからの値は文字列のため、(int) などでキャストしてから比較します。 |
| null チェック | === null | == null は0や空文字列とも一致するため誤判定が起きやすいです。 |
| 配列のソート | <=> を使った usort() | 大小比較をひとつの式で記述でき、コールバックを簡潔に書けます。 |
サンプルコード
comparison_loose.php
<?php
// 呪術廻戦のキャラクターのデータを使って == と === の挙動の違いを確認します
$cursedEnergyLevel = 0; // 整数の0(呪力が枯渇した状態)
$isDeactivated = false; // 真偽値のfalse
// ゆるい比較(==): 型変換が行われるため0とfalseが等しいと判定されます
if ($cursedEnergyLevel == $isDeactivated) {
echo "== : cursedEnergyLevel(0)と isDeactivated(false)は等しいと判定されました\n";
}
// 厳密比較(===): 型も比較するため int と bool は異なると判定されます
if ($cursedEnergyLevel !== $isDeactivated) {
echo "!== : cursedEnergyLevel(int)と isDeactivated(bool)は型が異なるため不一致です\n";
}
// フォームから受け取ったレベル(文字列)と整数のゆるい比較です
$inputLevel = "100"; // $_GET などから取得した場合は文字列になります
if ($inputLevel == 100) {
echo "== : 文字列の「100」と整数の100は等しいと判定されました(型変換が発生)\n";
}
// 厳密比較では型が異なるため不一致になります
if ($inputLevel !== 100) {
echo "!== : 文字列の「100」と整数の100は型が異なるため不一致です\n";
}
実行すると次のように出力されます。
php comparison_loose.php == : cursedEnergyLevel(0)と isDeactivated(false)は等しいと判定されました !== : cursedEnergyLevel(int)と isDeactivated(bool)は型が異なるため不一致です == : 文字列の「100」と整数の100は等しいと判定されました(型変換が発生) !== : 文字列の「100」と整数の100は型が異なるため不一致です
comparison_null.php
<?php // nullとの比較ではゆるい比較の落とし穴が特に出やすいため、=== を使います $technique = null; // 術式が未登録のキャラクター // ゆるい比較: null は 0・""・false と == で等しいと判定されます var_dump($technique == null); // bool(true) var_dump($technique == 0); // bool(true) — 意図しない一致 var_dump($technique == ""); // bool(true) — 意図しない一致 var_dump($technique == false); // bool(true) — 意図しない一致 echo "---\n"; // 厳密比較: === は値と型が完全一致した場合のみ true になります var_dump($technique === null); // bool(true) — 正確にnullだけに一致 var_dump($technique === 0); // bool(false) — int と null は型が異なります var_dump($technique === ""); // bool(false) — string と null は型が異なります var_dump($technique === false); // bool(false) — bool と null は型が異なります
実行すると次のように出力されます。
php comparison_null.php bool(true) bool(true) bool(true) bool(true) --- bool(true) bool(false) bool(false) bool(false)
comparison_spaceship.php
<?php
// 宇宙船演算子(<=>)を使ってキャラクターの呪力を降順にソートします
$characters = [
["name" => "五条悟", "cursedEnergy" => 1000],
["name" => "虎杖悠仁", "cursedEnergy" => 420],
["name" => "伏黒恵", "cursedEnergy" => 380],
["name" => "釘崎野薔薇", "cursedEnergy" => 310],
["name" => "夏油傑", "cursedEnergy" => 800],
];
// usort() のコールバックで宇宙船演算子を使います
// 降順にするため $b と $a の順番を逆にしています
usort($characters, function ($a, $b) {
return $b['cursedEnergy'] <=> $a['cursedEnergy'];
});
// ソート結果を出力します
foreach ($characters as $rank => $character) {
echo ($rank + 1) . "位: " . $character['name'] . "(呪力: " . $character['cursedEnergy'] . ")\n";
}
echo "\n";
// 宇宙船演算子の基本的な戻り値を確認します
var_dump(1 <=> 2); // int(-1) — 左辺が小さいです
var_dump(2 <=> 2); // int(0) — 等しいです
var_dump(3 <=> 2); // int(1) — 左辺が大きいです
実行すると次のように出力されます。
php comparison_spaceship.php 1位: 五条悟(呪力: 1000) 2位: 夏油傑(呪力: 800) 3位: 虎杖悠仁(呪力: 420) 4位: 伏黒恵(呪力: 380) 5位: 釘崎野薔薇(呪力: 310) int(-1) int(0) int(1)
次のように記述します。
<?php
// 呪術師のグレードをフォームから受け取った想定(すべて文字列)
$inputGrade = "1"; // $_POST['grade'] を想定
// 文字列のまま整数とゆるい比較しています
if ($inputGrade == 1) {
echo "グレード1の術師です\n";
}
文字列 "1" と整数 1 をゆるい比較(==)すると型変換が発生し、意図しない一致が起きることがあります。
<?php
// (int)でキャストしてから===で厳密比較します
$inputGrade = "1"; // $_POST['grade'] を想定
$grade = (int) $inputGrade;
if ($grade === 1) {
echo "グレード1の術師です\n";
}
// nullチェックは必ず===で行います
$domainExpansion = null; // 領域展開が未習得
if ($domainExpansion === null) {
echo "領域展開: 未習得です\n";
}
// nullでないことを確認してから処理します
$domainExpansionName = "無量空処";
if ($domainExpansionName !== null) {
echo "領域展開: " . $domainExpansionName . "\n";
}
実行すると次のように出力されます。
php comparison_strict_practice.php グレード1の術師です グレード1の術師です 領域展開: 未習得です 領域展開: 無量空処
よくあるミス
nullチェックを == で行い意図しない一致が起きる
『== null』は型変換が発生するため、null だけでなく 0・空文字列・false とも等しいと判定されます。null かどうかを正確に調べるには『=== null』を使います。
ng_null_check.php
<?php
$cursedEnergy = 0; // 呪力が枯渇した状態(nullではない)
// == null では 0 も null と等しいと判定される
if ($cursedEnergy == null) {
echo "術式が未登録です\n"; // 誤って実行される
}
実行すると次のように出力されます。
php ng_null_check.php 術式が未登録です
null かどうかを確認するには厳密比較『=== null』を使います。
ok_null_check.php
<?php
$cursedEnergy = 0;
$technique = null; // 術式が未登録
// === null は型も確認するため正確に null だけに一致する
if ($cursedEnergy === null) {
echo "cursedEnergy は null です\n";
} else {
echo "cursedEnergy は null ではありません(値: " . $cursedEnergy . ")\n";
}
if ($technique === null) {
echo "術式が未登録です\n";
}
実行すると次のように出力されます。
php ok_null_check.php cursedEnergy は null ではありません(値: 0) 術式が未登録です
フォーム入力値をキャストせずに整数と比較する
$_GET や $_POST から取得した値は文字列型です。ゆるい比較(==)で整数と比較すると型変換が発生し、意図しない一致が起きることがあります。
ng_form_compare.php
<?php
// フォームから受け取った等級(文字列)
$inputGrade = "1"; // $_POST['grade'] を想定
// 文字列 "1" と整数 1 をゆるい比較すると型変換が発生する
if ($inputGrade == 1) {
echo "1級術師です\n"; // 意図通りだが型変換に依存している
}
// 文字列 "0" と false をゆるい比較すると等しいと判定される
$status = "0";
if ($status == false) {
echo "false と判定されました\n"; // 意図しない一致
}
実行すると次のように出力されます。
php ng_form_compare.php 1級術師です false と判定されました
外部から受け取った値は明示的にキャストしてから厳密比較します。
ok_form_compare.php
<?php
$inputGrade = "1";
// (int) でキャストしてから === で比較する
$grade = (int) $inputGrade;
if ($grade === 1) {
echo "1級術師です\n";
}
// 文字列として比較したい場合はそのまま === を使う
$status = "active";
if ($status === "active") {
echo "ステータス: 現役\n";
}
実行すると次のように出力されます。
php ok_form_compare.php 1級術師です ステータス: 現役
概要
PHPの比較演算子は『==』(ゆるい比較)と『===』(厳密比較)の2種類があります。『==』は型変換を行うため、『0 == false』や『null == 0』が『true』になるなど直感に反する結果を生じることがあります。型変換の詳細については『型キャスト』を参照してください。バグを防ぐためにも、原則として値と型の両方を確認する『===』と『!==』を使用してください。特に外部から受け取った値を比較する際は、明示的にキャストしてから厳密比較するのが安全です。
否定の不等値演算子には『!=』と『!==』があります。『!=』は『==』と同様に型変換を行うゆるい比較で、『!==』は型変換を行わない厳密比較です。また、『<>』は『!=』と同義ですが、現在のコードでは『!=』を使うのが一般的です。
宇宙船演算子(『<=>』)はPHP 7以降で使えます。左辺が小さければ『-1』、等しければ『0』、大きければ『1』を返すため、『usort()』のコールバックを簡潔に記述するのに便利です。比較演算子を条件分岐で使う場面については『if / elseif / else』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。