はじめに
PHP7系から追加されたnull合体演算子(??)とPHP5.3系から使えるエルビス演算子(?:)
これらがよくごっちゃになってしまうので、この機会にしっかり使い分けを覚えていこうと思います。
エルビス演算子
まずはエルビス演算子(?:)から。
エルビスプレスリーに似ていることから命名されたらしいです。
演算子界のキング・オブ・ロックンロールですね。
エルビス演算子を使うと
三項演算子でこのように書いていたところを
$a ? $a : $b;
こう書くことができます。
$a ?: $b;
三項演算子の第二項が省略できるなんて、確かにこれはロックです。
具体例
それでは具体的な例を書いてみましょう。
$name = 'カバオ';
echo '名前: '. $name ?: 'うさこ';
この場合は 名前: カバオ と表示されますが、
変数をブランクで定義すると
$name = '' ;
echo '名前: '. $name ?: 'うさこ';
この場合は 名前: うさこ になりました。
PHPでfalse判定されるものでやってみると以下のような結果になりました。
第一項の値 | 例 | 評価された項 |
---|---|---|
'' | $name = ''; | 第2項 |
null | $name = null; | 第2項 |
未定義の変数 | error | |
空配列 | $name = []; | error |
0 | $name = 0; | 第2項 |
'0' | $name = '0'; | 第2項 |
false | $name = false; | 第2項 |
セットされていない変数 | $name; | error |
未定義・空配列・セットされていない変数以外は、基本的に、第二項が評価されることがわかります。
NULL合体演算子
では本題のNULL合体演算子(??)を見ていきましょう。
こちらは残念ながら、特に面白いエピソードはありません。
エルビス演算子と違って、nullじゃなければ第一項に落ちてきます。
具体例
三項演算子で書くとこういうことになります。
!is_null($a) ? $a : $b
これがNULL合体演算子だとこのように書けてしまいます。
$a ?? $b;
では先ほどと同様にやってみるとどうなるでしょうか。
$name = 'カバオ';
echo '名前: '. $name ?? 'うさこ';
この場合は 名前: カバオ と表示されますが、
$name = '' ;
echo '名前: '. $name ?? 'うさこ';
この場合は**名前: **になってしまいました。
うさこはいずこへ
nullかどうかをチェックするため、空文字列ならnullでないと評価され、そのものが表示されてしまうんですね。
なのでnullを定義してあげると
$name = null;
echo '名前: '. $name ?? 'うさこ';
名前:うさこ になりました。
うさこおかえり
先ほど同様にPHPでfalse判定されるものでやってみるとこうなります。
第一項の値 | 例 | 評価された項 |
---|---|---|
'' | $name = ''; | 第1項 |
null | $name = null; | 第2項 |
未定義の変数 | 第2項 | |
空配列 | $name = []; | 第1項 |
0 | $name = 0; | 第1項 |
'0' | $name = '0'; | 第1項 |
false | $name = false; | 第1項 |
セットされていない変数 | $name; | 第1項 |
nullと未定義変数以外は全て第一項に落ちてきました。
結局いつ使うのか?
NULL合体演算子結局いつ使えるのでしょうか。
ここでは、使える2パターンを紹介して終わります。
① isset地獄から抜けられる
NULL合体演算子の良いところは第一項が存在しない変数でもnoticeが発生しないところ。
if (isset($_POST['action'])) {
$action = $_POST['action'];
} else {
$action = 'default';
}
こんなときにissetしなくていいので便利です。
↓NULL合体演算子を使うとこんなにスッキリ。
$action = $_POST['action'] ?? 'default';
② 複数の演算子をつなげて使用できる
$a = null;
$b = null;
$c = 0;
$result = $a ?? $b ?? $c;
echo $result; // 0
AがnullであればBを代入、さらにBがnullであればCを代入する」ということができます。
コードがすっきりと書けるのはいいですが、
使いようによっては可読性が損なわれてしまうので、場面で使い分けたいと思います。