PHP入門 比較演算子
左辺と右辺の値を比較し、その結果をtrue/falseとして返します。比較演算子は、if、while、do~whileのような条件分岐/繰り返し命令で条件式を表すために使用します。
主な比較演算子
演算子 | 概要 | 用途 |
---|---|---|
== | 左辺と右辺の値が等しい場合はtrue | 7==7 結果:true |
=== | 左辺と右辺の値が等しく、かつ、同じデータ型である場合はtrue | 7===’7′ 結果:false |
!= | 左辺と右辺の値が等しくない場合にtrue | 7!=7 結果:false |
<> | 左辺と右辺の値が等しくない場合にtrue | 7<>7 結果:false |
!== | 左辺と右辺の値が等しくない、または同じデータ型ではない場合にtrue | 7!==’7′ 結果:true |
< | 左辺が右辺より小さい場合にtrue | 7<10 結果:true |
> | 左辺が右辺より大きい場合にtrue | 7>10 結果:false |
<= | 左辺が右辺以下の場合にtrue | 7<=10 結果:true |
>= | 左辺が右辺以上の場合にtrue | 7>=10 結果:false |
<=> | 宇宙船演算子。左辺が右辺より小さい場合には-1、左辺と右辺が等しい場合は0、左辺が右辺より大きい場合は1 | 7<=>10 結果:-1 |
?: | 条件演算子。「条件式?式1:式2」。条件式がtrueの場合は式1、falseの場合は式2 | (10>7)?’正しい’:’間違い’ 結果:正しい |
?? | null合体演算子。左辺がnullでなければその値、左辺がnullならば右辺の値、左辺も右辺もnullの場合はnull | null ?? 10 結果:10 |
文字列混在の比較
等価演算子「==」は、数値と文字列を比較するときに、文字列を数値に変換した上で比較しようとします。また、文字列同士の比較であっても、数値形式の文字列である場合には、同じく数値に変換したものを比較しようとします。
PHP8前の挙動
<?php
var_dump('3.14' == 3.140000); //結果:bool(true) ➊
var_dump('3.14E2' == 314); //結果:bool(true) ➋
var_dump('0x10' == 16); //結果:bool(false) ➌
var_dump('010' == 8); //結果:bool(false) ➍
var_dump('0b11' == 3); //結果:bool(false) ➎
var_dump('13xyz' == 13); //結果:bool(true) ➏
var_dump('X' == 0); //結果:bool(true) ➐
var_dump('3.14' == '3.14000'); //結果:bool(true) ➑
var_dump('3.14E2' == '314'); //結果:bool(true) ➒
var_dump('13xyz' == '13'); //結果:bool(false) ➓
➊から➐は、文字列と数値の比較です。’3.14’の小数点はもちろん、’3.14E2’のような指数表記も、浮動小数点リテラルとみなされ、正しく比較されます。
➌から➎の2/8/16進数リテラルは正しく認識されません。’0x10’、’0b11’は文字列以降が切り捨てられた結果、0と見なされます。’010’はそのまま10と認識されるので、いずれも条件式はfalseとなります。
➏の数値と文字列混在は先頭の数値だけが認識されるのでtrueとなります。
➐は’X’は数値に変換するとゼロのためtrueと評価されます。
➓については、文字列同士の比較のため片方が純粋な数値文字列でない場合、数値に変換されません。したがって「’13xyz’ == ’13’」は異なる文字列とみなされ、結果はfalseとなります。
PHP8での挙動
PHP8では、➏、➐の挙動が変化し、いずれもfalseになります。
厳密な等価演算子(===)
「===」演算子は「厳密な等価演算子」と呼ばれ、値を比較する際に値とデータ型が厳密に一致するかどうかを判定します。できるだけ、「===」演算子を使用することを勧めます。
<?php
var_dump('3.14E2' == 314); //結果:bool(false)
var_dump('X' == 0); //結果:bool(false)
var_dump('1' == 1); //結果:bool(false) ➊
➊については、左辺/右辺とも1ですが、クォートで囲まれているため文字列リテラル、右辺は整数リテラルとみなされ、falseを返します。
浮動小数点の比較
浮動小数点は内部的に2進数として扱われるため、厳密な比較ができません。浮動小数点同士を比較する場合は、次の方法を使用します。
<?php
const EPSILON = 0.00001;
$x = 0.123456;
$y = 0.123455;
var_dump(abs($x - $y) < EPSILON ); //結果:bool(true)
定数EPSILONは、誤差の許容範囲を表します。計算機イプシロン、丸め単位などとも呼ばれます。今回の例では、小数第5位までの精度を保証したいので、イプシロンは0.00001とします。後は、浮動小数点数同士の差を求め(absは絶対値を求める関数です)、その値がイプシロン未満であれば、保証した桁数までは等しいということになります。
配列の比較
配列同士の比較にも、「==」「===」「!=」「<>」「!==」「>」「<」「>=」「<=」演算子を利用できます。配列の比較は次の順序で行われます。
- 要素数で比較(要素数の少ない配列がより小さい)
- 要素数が等しい場合、同じキーを持つ要素同士で値の大小を比較(より大きい要素/より小さい要素がみつかったところで判定終了)
- 1.、2.の比較がすべて等しい場合、両者は等しいとみなされる
ただし、2で左辺の配列が持つキーを右辺の配列が持たなかった場合、比較は失敗します。
<?php
$data01 = [1, 2, 3];
$data02 = [1, 5];
var_dump($data01 < $data02); //結果:bool(false)➊
$data11 = [1, 2, 3];
$data12 = [1, 5, 1];
var_dump($data11 < $data12); //結果:bool(true)➋
$data11 = [1, 2, 3];
$data12 = [1, 2, '3'];
var_dump($data21 == $data22); //結果:bool(true)➌
var_dump($data21 === $data22); //結果:bool(false)➍
$data31 = ['A' => 'a', 'B' => 'b', 'C' => 'c'];
$data32 = ['A' => 'a', 'C' => 'c', 'B' => 'b'];
var_dump($data31 == $data32); //結果:bool(true)➎
var_dump($data31 === $data32); //結果:bool(false)➏
- ➊は、$data01の要素数は$data02よりも多いので、$data01は$data02よりも大きいとみなされます。
- ➋要素数はどちらも一緒なので、比較演算子は要素個々の大小を比較します。2番目の要素が「2<5」なので、「$data01<$data02」であると評価されます。3番目の要素「3>1」は無視されます。
- ➌は要素数も等しく、対応する要素同士も等しいのでtrueを返します。➍は、厳密な等価演算子「===」は「3 <> ‘3’」とみなしfalseを返します。
- ➎と➏は連想配列を「==」「===」演算子で比較したものです。$data31と$data32の違いは、要素の並び順だけです。この場合、「==」演算子はtrueを返しますが、「===」演算子はfalseを返します。厳密な等価演算子は、要素数とキ-/値の組み合わせに加えて、要素の並び順も判定の対象となります。
条件演算子(?:)
条件演算子は、指定された条件式の真偽に応じて、対応する式の値を出力します。
<?php
$score = 75;
print $score >= 70 ? '合格' : '不合格' //結果:合格
条件演算子の省略構文
条件演算子には、省略構文が2種類あります。
1、式1 ?: 式2
式1がtrueに変換できる場合には式1を、そうでない場合には式2を返します。省略構文は、変数が空文字列やnull、ゼロなど特殊な値を取る場合に、異なる出力をさせたいようなケースに役立ちます。
<?php
$message = '';
print $message ?: '空です。'; //結果:空です。
非省略構文
print $message ? $message : '空です。';
2、式1 ?? 式2
式1がnullでない場合には式1を、さもなければ式2を返します。null合体演算子とも呼ばれます。
<?php
//$message = 'ハロー';
print $message ?? 'ノーコメント'; //結果:ノーコメント
「?:」演算子は式1がfalseとみなせる(=空文字列やゼロ、空配列、nullなどである)場合に、式2を出力していました。しかし「??」演算子ではnullである場合にだけ式2を出力します。
非省略構文
print isset($message) ? $message : 'ノーコメント';
条件演算子を列記する場合の注意
条件演算子を複数列記した場合の挙動は難解です。PHP7.4では推奨されておりません。また、PHP8.xではエラーとなります。
PHP7.3までの挙動
結果は「OK」となります。条件演算子は、左から順に解釈されます。
<?php
print true ? 1 : false ? 'OK' : 'NG';
よりわかりやくすカッコでまとめると以下のようになります。
<?php
print (true ? 1 : false) ? 'OK' : 'NG';
もし結果として1を期待するならば、以下のようにカッコでくくります。
<?php
print true ? 1 : (false ? 'OK' : 'NG');
条件演算子を複数列記する場合には、常にカッコでくくるのがよいでしょう。