はじめに
どれもよく見かけるしよく使うけど、混同しやすいと個人的に感じるので違いをまとめたいと思います。
??(NULL合体演算子)
この演算子は、もし第一オペランドが非nullの値であればそれを返し、そうでない場合は第二オペランドを返します
非nullとはnullではないかつ、未定義(Undefined)ではないという意味です。
「値の存在チェックした上で、値が存在しなければデフォルト値を設定する」
これをたったクエスチョンマーク2つで実現できるのがNULL合体演算子です。
ポイントは大きく2つです。
①未定義の値もnullと見なされて、右辺が返る
非nullと聞くと「Undefinedとnullとは違うからUndefinedも非nullだ!」と、思いがちですがUndefinedでも右辺が返ります。
$hoge = "ほげほげ";
$result = $fuga ?? "ぴよぴよ"
echo $result // ぴよぴよ
// $hogeは定義されているが、$fugaは未定義なので右辺の「ぴよぴよ」が返っている。
②Falsyな値も非nullと見なされて左辺が返る
空文字や0はFalsyですが、非nullなので左辺が返ります。
$result = 0 ?? "ぴよぴよ"
echo $result // 0
// 左辺は非nullなので、「0」が返っている。
isset
値が非nullであればtrueを返します。
繰り返しですが、つまりnullではないかつ、未定義(Undefined)ではない状態です。
nullか未定義(Undefined)であればfalseを返します。
empty
変数が空であるかどうかを検査します。 変数が空であるとみなされるのは、変数が存在しない場合や 変数の値が false に等しい場合です。
空文字や0のようなFalsyな値もemptyと見なされてtrueが返ってくるので注意です。
使い分け
null合体演算子
→存在していること期待しているが、存在しない・nullならデフォルト値を用意したい
isset
→存在していること期待している(なんらかの処理を行う前のエラー回避など)
empty
→存在しないことを期待している(エラーハンドリングなど)
最初からif($hoge)
で判定すれば楽では?
$fugaの値が存在しない場合、未定義の値を参照してしまい意図しないエラーが発生してしまいます。
$hoge = "ほげほげ";
if($fuga){
}
// エラー発生!
さいごに
いつも何気なく使っていたものですが、執筆を通して理解が深まりました。
否定論理演算子の!
があると、issetやemptyは読みづらくなるので目的に応じて適切に使い分けたいです。
また、デフォルト値を用意したい時は積極的にNULL合体演算子を使いたいと思います。
参考
早見表を作っていただいていた方がいらっしゃったのでこちらも参考に