この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:5
ページ更新者:guest
更新日時:2026-06-11 07:10:02

タイトル: 比較演算子
SEOタイトル: PHP 比較演算子の徹底解説(== / === / <=> / Type Juggling / PHP 8 変更)

この記事の要点
  • == (緩い比較) は型変換あり、=== (厳密比較) は型も一致が必要
  • 原則 === を使う==0 == "abc" の罠など事故が多い
  • 宇宙船演算子 <=>(PHP 7+): 左 < 右 で -1、等しい 0、左 > 右 で 1。usort で便利
  • PHP 8: 文字列と数値の比較ルール変更。0 == "abc"true → false
  • 配列: == は要素同士を緩く比較、=== は型・順序まで完全一致

演算子一覧

演算子名前意味結果
$a == $b等しい型変換後に等しいかbool
$a === $b厳密に等しい型まで含めて等しいかbool
$a != $b / $a <> $b等しくない緩い不等価bool
$a !== $b厳密に等しくない厳密な不等価bool
$a < $b未満小なりbool
$a > $b超過大なりbool
$a <= $b以下小なりイコールbool
$a >= $b以上大なりイコールbool
$a <=> $b宇宙船 (Spaceship)-1 / 0 / 1 を返すint
$a ?? $bNull 合体$a が null なら $b

== (緩い比較) と === (厳密比較)

<?php
// 数値の比較
var_dump(1 == 1);            // bool(true)
var_dump(1 === 1);           // bool(true)

// 型が違うとき
var_dump(1 == '1');          // bool(true)   ← 文字列が数値に変換される
var_dump(1 === '1');         // bool(false)  ← 型が違うので false

var_dump(true == 1);         // bool(true)
var_dump(true === 1);        // bool(false)

var_dump(null == false);     // bool(true)
var_dump(null === false);    // bool(false)

var_dump(null == 0);         // bool(true)
var_dump(null === 0);        // bool(false)

var_dump('' == null);        // bool(true)
var_dump('' === null);       // bool(false)

原則: === を使う

== の罠は実際の事故に直結します。意図して緩く比較したい場合以外は === を使ってください:

<?php
// よくあるバグ例
$found = array_search('needle', $haystack);
if ($found == false) {       // ❌ 0 番目に見つかると false 扱い
    echo '見つからない';
}
if ($found === false) {      // ✅ 厳密比較で本当に false かを判定
    echo '見つからない';
}

// strpos も同じ問題
if (strpos($s, 'abc') == false) {     // ❌
if (strpos($s, 'abc') === false) {    // ✅

// パスワードチェック
if ($_POST['token'] == $expected_token) {     // ❌ 危険
if (hash_equals($expected_token, $_POST['token'])) {  // ✅ タイミング攻撃にも安全

PHP 8 での文字列・数値比較の変更

PHP 7 までは数値文字列でない文字列も数値に変換して比較していました。PHP 8 で挙動が変わっています:

PHP 7PHP 8
0 == "abc"true ("abc" → 0)false (数値→文字列で比較)
0 == ""truefalse
0 == "0"truetrue (両方とも数値文字列扱い)
10 == "10abc"truefalse + Warning
10 == "10"truetrue
<?php
// PHP 8 では「両者を文字列として」比較する (数値が文字列に)
var_dump(0 == 'abc');        // PHP 7: true / PHP 8: false

// 両者が数値文字列の場合のみ数値比較
var_dump(0 == '0');          // 両バージョン true
var_dump(100 == '100');      // 両バージョン true
var_dump(100 == '100.0');    // 両バージョン true

宇宙船演算子 <=> (PHP 7+)

並べ替え (usort) や 3 項比較に便利:

<?php
// 基本: -1 / 0 / 1 を返す
var_dump(1 <=> 2);           // int(-1)
var_dump(2 <=> 2);           // int(0)
var_dump(3 <=> 2);           // int(1)

var_dump('a' <=> 'b');       // int(-1)
var_dump([1, 2] <=> [1, 3]); // int(-1)

// usort で並べ替え
$users = [
    ['name' => 'Bob', 'age' => 30],
    ['name' => 'Alice', 'age' => 25],
];

usort($users, fn ($a, $b) => $a['age'] <=> $b['age']);
// → 年齢の昇順

// 複合キー
usort($users, fn ($a, $b) =>
    $a['age'] <=> $b['age']                  // 第一に年齢
    ?: strcmp($a['name'], $b['name'])         // タイブレーカーで名前
);

Null 合体演算子 ?? と ??= (PHP 7+)

<?php
// 従来: isset で 3項
$name = isset($_GET['name']) ? $_GET['name'] : 'Guest';

// Null 合体演算子 (PHP 7+)
$name = $_GET['name'] ?? 'Guest';

// 連鎖可能
$name = $_GET['name'] ?? $_POST['name'] ?? $defaultName ?? 'Guest';

// Null 合体代入 (PHP 7.4+)
$config['timeout'] ??= 30;   // null か未定義なら 30

// 注意: ?? は null と未定義に true。'' や 0 は通す
$x = '' ?? 'default';        // ''
$x = 0  ?? 'default';        // 0
$x = null ?? 'default';      // 'default'

配列の比較

<?php
$a = ['x' => 1, 'y' => 2];
$b = ['y' => 2, 'x' => 1];        // 順序違い
$c = ['x' => '1', 'y' => '2'];    // 型違い

var_dump($a == $b);          // bool(true)  ← キーと値が一致すれば順序不問
var_dump($a === $b);         // bool(false) ← 順序まで含めて厳密比較
var_dump($a == $c);          // bool(true)  ← 緩い比較で型変換
var_dump($a === $c);         // bool(false) ← 型違い

// 数値添字配列
var_dump([1,2,3] === [1,2,3]); // true
var_dump([1,2,3] === [3,2,1]); // false (順序違い)

オブジェクトの比較

<?php
class Point { public function __construct(public int $x, public int $y) {} }

$p1 = new Point(1, 2);
$p2 = new Point(1, 2);
$p3 = $p1;

var_dump($p1 == $p2);        // bool(true)   ← 同じクラス + 同じプロパティ値
var_dump($p1 === $p2);       // bool(false)  ← インスタンスが別物
var_dump($p1 === $p3);       // bool(true)   ← 同じインスタンス参照

Type Juggling (型ジャグリング) のルール

異なる型を == で比較したときの変換ルール(PHP 8 ベース):

比較方法
null / boolany両者を bool に変換
int / float数値文字列両者を数値として比較
int / float非数値文字列PHP 8: 文字列として比較
stringstring文字列比較
arrayarray要素同士を比較
objectobject同クラス + プロパティ一致

FAQ

Q: switch 文の中での比較は?
A: switch== 相当(緩い比較)。意図しない一致を避けたいときは match(PHP 8+)が === 相当で安全。

Q: in_array の比較は?
A: 既定で == 緩い比較。in_array($needle, $arr, true) の第 3 引数 true で === 厳密比較に。常に true を指定を推奨。

Q: 浮動小数の比較
A: 0.1 + 0.2 == 0.3 は false。abs($a - $b) < PHP_FLOAT_EPSILON 等で許容誤差比較を。