Php/docs/language.operators.comparison

提供:Dev Guides
< Php
移動先:案内検索

比較演算子

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

比較演算子
名前 結果
$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 より大きいか、0か、0より小さい場合に、 それぞれ、0より大きい か、0か、0より小さい int

オペランドが両方 数値形式の文字列 の場合、 もしくは一方が数値で、もう一方が 数値形式の文字列 の場合、 比較は数値として行われます。 これらのルールは switch 文にも適用されます。 型の変換は 演算子が ===!== の場合は行われません。 なぜなら、これらの演算子は、値と型を両方比較するものだからです。

警告 PHP 8.0.0 より前のバージョンでは、 文字列が数値または数値形式の文字列の場合、文字列は比較する前に数値に変換されていました。 これによって、以下の例で見られるような驚きの結果が生じる場合があります:

<?phpvar_dump(0 == "a"); // 0 == 0 -> truevar_dump("1" == "01"); // 1 == 1 -> truevar_dump("10" == "1e1"); // 10 == 10 -> truevar_dump(100 == "1e2"); // 100 == 100 -> trueswitch ("a") {case 0:    echo "0";    break;case "a": // "a" は 0 にマッチするので、決してここにはたどりつきません    echo "a";    break;}?>

<?php  // Integerecho 1 <=> 1; // 0echo 1 <=> 2; // -1echo 2 <=> 1; // 1 // Floatecho 1.5 <=> 1.5; // 0echo 1.5 <=> 2.5; // -1echo 2.5 <=> 1.5; // 1 // 文字列echo "a" <=> "a"; // 0echo "a" <=> "b"; // -1echo "b" <=> "a"; // 1 echo "a" <=> "aa"; // -1echo "zz" <=> "aa"; // 1 // 配列echo [] <=> []; // 0echo [1, 2, 3] <=> [1, 2, 3]; // 0echo [1, 2, 3] <=> []; // 1echo [1, 2, 3] <=> [1, 2, 1]; // 1echo [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 組み込みクラスには独自の比較基準が定義されています。

異なるクラスは比較できません。同じクラスであるかどうかは ここで説明されています

string, resource, int または float string, resource, int または float 文字列やリソースを数値に変換し、算術演算を行います
array array 要素数の少ない配列のほうが小さくなります。オペランド 1 のキーが

オペランド 2 に存在しない場合、配列は比較できません。そうでない場合は 個々の要素の値を比較します(以下の例を参照ください)

object あらゆる型 object のほうが常に大きくなります
array あらゆる型 array のほうが常に大きくなります

例1 Boolean/null comparison

<?php// Bool and null are compared as bool alwaysvar_dump(1 == TRUE);  // TRUE - same as (bool)1 == TRUEvar_dump(0 == FALSE); // TRUE - same as (bool)0 == FALSEvar_dump(100 < TRUE); // FALSE - same as (bool)100 < TRUEvar_dump(-10 < FALSE);// FALSE - same as (bool)-10 < FALSEvar_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}?>

警告 ふたつの 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) という式は、式1true の場合に 式2 を、 式1false の場合に 式3 を値とします。 三項演算子のまんなかの部分をなくすこともできます。 式 expr1 ?: expr3 の結果は、expr1true と同等の場合は expr1、 それ以外の場合は expr3 となります。

注意:

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

注意:

三項演算子を "積み重ねて" 使用することは避けましょう。 ひとつの文の中で複数の三項演算子を使用した際の PHP の振る舞いは、 他のプログラミング言語のそれと比べて、少々わかりにくいものです。 PHP 8.0.0 より前のバージョンでは、三項演算子は左から右に評価されていました。 他の殆どのプログラミング言語では、右から左に評価されます。

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

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

Null 合体演算子

"??" 演算子 (null 合体演算子) を使うことが出来ます。

例5 デフォルト値の代入

<?php// Null 合体演算子の使用例$action = $_POST['action'] ?? 'default';// 上の文は、この if/else 文と同じ意味ですif (isset($_POST['action'])) {    $action = $_POST['action'];} else {    $action = 'default';}?>

(expr1) ?? (expr2) は、 expr1null である場合は expr2 と評価され、それ以外の場合は expr1 と評価されます。 この演算子は、左側の値が存在しない場合でも notice や warning が発生しません。 isset() と同じ挙動です。 これは、配列のキーを扱う場合に便利です。

注意:

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

注意:

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

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

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