LoginSignup
152
139

More than 3 years have passed since last update.

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

Last updated at Posted at 2018-06-17

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

エルビス演算子 ?:

公式サイトには単体での説明はなく、三項演算子の項目に説明がありました。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

【2020/4/8 追記】
いただいたコメントによると「issetはgetterによる値の取得を試行しない」とのことで、正しくは 「!is_null(expr1) ? expr1 : expr2 と同様」のようです。

色々な値で検証してみる

以前、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. ここを誤解して覚えていました 

152
139
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
152
139