かきスタンプ

福岡でフリーランスの物流系のエンジニアやってます。

PHP:エルビス演算子【(expr1) ? (expr2) : (expr3) 】と、Null合体演算子【(expr1) ?? (expr2)】は、「??」を使った方が無難かも。

とてもよく似ている以下の2つの演算子

主な違いは以下の点でしょうか。

  • ? は、「0」「"0"」「空の配列」を false と判定し、右辺の値を返す
  • ?? は、「0」「"0"」「空の配列」を true と判定し、その値を返す

0 や "0" を、「値がセットされていない状態」として扱うかどうかはシステムによって変わってくると思うので、これらを初期値に置き換えない Null合体演算子(??)を使った方が、予期せぬ不具合を起こしにくいのでは?
という話。
 
以下、構文の説明と実行結果。
PHP ver 7.1.32 で実行しています。

エルビス演算子

https://www.php.net/manual/ja/language.operators.comparison.php#language.operators.comparison.ternary

(expr1) ? (expr2) : (expr3)
 
expr1 が TRUE の場合に expr2 を、 expr1 が FALSE の場合に expr3 を値とする。
 
式 expr1 ?: expr3 の結果は、expr1 が TRUE と同等の場合は expr1、 それ以外の場合は expr3 となります。

実行結果

var_dump(     "a" ? "a"     : "not_exists" );  //=> "a"
var_dump(     "0" ? "0"     : "not_exists" );  //=> "not_exists"
var_dump(   "0.0" ? "0.0"   : "not_exists" );  //=> "0.0"
var_dump(  "0x00" ? "0x00"  : "not_exists" );  //=> "0x00"
var_dump(       0 ? 0       : "not_exists" );  //=> "not_exists"
var_dump(     0.0 ? 0.0     : "not_exists" );  //=> "not_exists"
var_dump(    0x00 ? 0x00    : "not_exists" );  //=> "not_exists"
var_dump( array() ? array() : "not_exists" );  //=> "not_exists"
var_dump(    NULL ? NULL    : "not_exists" );  //=> "not_exists"
var_dump(   FALSE ? FALSE   : "not_exists" );  //=> "not_exists"
var_dump( $undefined_variable ? $undefined_variable : 'not_exists' );  //=> "not_exists"  ※Noticeが出る

"0" は false で、"0.0" が true というのが、何だかややこしい。

Null 合体演算子(7~)

https://www.php.net/manual/ja/language.operators.comparison.php#language.operators.comparison.coalesce

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

実行結果

var_dump(     "a" ?? "not_exists" );  //=> "a"
var_dump(     "0" ?? "not_exists" );  //=> "0"
var_dump(   "0.0" ?? "not_exists" );  //=> "0.0"
var_dump(  "0x00" ?? "not_exists" );  //=> "0x00"
var_dump(       0 ?? "not_exists" );  //=> 0
var_dump(     0.0 ?? "not_exists" );  //=> 0
var_dump(    0x00 ?? "not_exists" );  //=> 0
var_dump( array() ?? "not_exists" );  //=> array(0) {}
var_dump(    NULL ?? "not_exists" );  //=> "not_exists"
var_dump(   FALSE ?? "not_exists" );  //=> "not_exists"
var_dump( $undefined_variable  ?? "not_exists" );  //=> "not_exists"  ※Noticeが出ない

こっちは "0" も "0.0" も true。