Posted at

似てるようで違う、PHPのエルビス演算子とNull合体演算子

More than 1 year has passed since last update.

細かい部分を若干間違えて覚えており、危うくバグを出すところだったので、きちんと調べ直しました。


エルビス演算子 ?:

公式サイトには単体での説明はなく、三項演算子の項目に説明がありました。PHP 5.3 以降で使用可能です。

三項演算子


式 expr1 ?: expr3 の結果は、expr1 が TRUE と同等の場合は expr1、 それ以外の場合は expr3 となります。


要するに、expr1 ? expr1 : expr3のシンタックスシュガーということですね。


Null 合体演算子 ??

こちらは独立した項目として説明されていました。PHP 7 以降で使用可能です。

Null 合体演算子


式 (expr1) ?? (expr2) は、 expr1 が NULL である場合は expr2 と評価され、それ以外の場合は expr1 と評価されます。

この演算子は、左側の値が存在しない場合でも notice が発生しません。


isset(expr1) ? expr1 : expr2と同様の結果になります。

expr1がNULLや未定義でなければexpr1と評価されるので、falsyな値になる場合もあります。1


色々な値で検証してみる

以前、PHP/JavaScriptの真偽と型という記事で色々な値の真偽を調べましたが、その時と同様のデータで2つの演算子の結果を調べてみました。

$aの値
エルビス演算子
$a ?: $b

Null合体演算子
$a ?? $b

TRUE
TRUE
TRUE

FALSE
$bの値
FALSE

-1
-1
-1

0
$bの値
0

1
1
1

-0.1
-0.1
-0.1

0.0
$bの値
0.0

0.1
0.1
0.1

文字列 'a'
'a'
'a'

空文字列 ''
$bの値
''

文字列のゼロ '0'
$bの値
'0'

NULL
$bの値
$bの値

空の配列 array()
$bの値
array()

空でない配列 array(0)
array(0 => 0)
array(0 => 0)

空のオブジェクト new stdClass()
stdClass::__set_state(array( ))
stdClass::__set_state(array( ))

未定義の変数 $none

$bの値
Notice: Undefined variable が発生し、nullとして評価された結果)

$bの値
(Noticeは発生しない)

未定義のインデックス $my_array['none']

$bの値
Notice: Undefined index が発生し、nullとして評価された結果)

$bの値
(Noticeは発生しない)

未定義のプロパティ $my_object->none

$bの値
Notice: Undefined property が発生し、nullとして評価された結果)

$bの値
(Noticeは発生しない)

表にはありませんが、エルビス演算子が$a ? $a : $bと同じで、Null合体演算子とisset($a) ? $a : $bが同じ結果になることも検証してあります。

\$aが未定義の可能性がある場合は、エルビス演算子を使わずに!empty($a) ? $a : $bとするのが安全ですね。





  1. ここを誤解して覚えていました