null合体演算子とnullsafe演算子で分岐を減らす
null合体演算子(??)とnullsafe演算子(?->)は、値やオブジェクトがnullかどうかのチェックを短く書くための演算子です。冗長なisset分岐を減らして、コードの主旨を見えやすくします。
PHPで「値がなければデフォルト」「オブジェクトがあればメソッド呼ぶ」を書くとき、isset地獄になりがちです。??と?->を使うと、その手のnullチェックがぐっと短くなります。
?? は「なければこっち」
// 昔
$name = isset($_GET['name']) ? $_GET['name'] : 'ゲスト';
// 今
$name = $_GET['name'] ?? 'ゲスト';
左辺が未定義またはnullのときだけ右辺が使われます。空文字や0は「値あり」と判定される点に注意です。「空文字もデフォルト扱いにしたい」なら?:(エルビス演算子)の出番ですが、こちらは未定義キーで警告が出るので用途が違います。
??= で代入もまとめる
$config['timeout'] ??= 30; // timeoutが未設定なら30をセット
?-> はチェーンの途中でnullなら止まる
$city = $user?->getAddress()?->city;
途中がnullになった時点で式全体がnullになり、そこで打ち切られます。「userがいれば住所を取り、住所があれば市名を取る」を1行で書けるわけです。
まとめ
??はデフォルト値、?->はチェーン途中のnull回避。この2つを使うと、本質的でないnullチェックが減って、コードの主旨が見えやすくなります。ただし?->を多用すると「どこでnullになったのか」が見えにくくなるので、原因を追いたい箇所ではあえて明示的にチェックするほうがいいこともあります。
よくある質問
Q. ??と?:(エルビス演算子)はどう違いますか。
A. ??は左辺が未定義またはnullのときだけ右辺を使い、空文字や0は「値あり」とみなします。?:は空文字や0もfalsyとして右辺に倒れ、未定義キーでは警告が出ます。
Q. ?->はどんなときにnullを返しますか。
A. チェーンの途中がnullになった時点で式全体がnullになり、その先は評価されません。「userがいれば住所、住所があれば市名」を安全に1行で書けます。