とてもよく似ている以下の2つの演算子。
主な違いは以下の点でしょうか。
- ? は、「0」「"0"」「空の配列」を false と判定し、右辺の値を返す
- ?? は、「0」「"0"」「空の配列」を true と判定し、その値を返す
0 や "0" を、「値がセットされていない状態」として扱うかどうかはシステムによって変わってくると思うので、これらを初期値に置き換えない Null合体演算子(??)を使った方が、予期せぬ不具合を起こしにくいのでは?
という話。
以下、構文の説明と実行結果。
PHP ver 7.1.32 で実行しています。
エルビス演算子
(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~)
式 (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。