Menu

PHPのnull合体演算子:??と??=の使い方

PHPのnull合体演算子は、左辺がnullか未設定でない限り左辺を返します:$name = $_GET['name'] ?? 'Guest';。存在しない変数や配列キーについて警告を出しません。??の連鎖、??=による代入、??と?:の違い、nullsafe演算子?->を学びます。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

??は、左側の値が存在してnullでなければその値を、そうでなければ右側の値を返します:$name = $_GET['name'] ?? 'Guest';。キーを直接読む場合と違い、変数や配列キーが存在しなくても警告を出しません。

最初の実行ではクエリ文字列がないので、どちらも既定値が使われます。PageタブのリンクをクリックするとURLの値が$_GETに入った状態でスクリプトがもう一度実行されます。その最初の実行で??なしに$_GET["name"]を読むと、通常のPHPの設定ではWarning: Undefined array key "name"が表示されます。リクエストのデータについてはGETと_GETと_POSTのページで詳しく説明しています。

??はisset()チェックの短縮形

$a ?? $bはisset($a) ? $a : $bとまったく同じ意味です。変数、任意の深さの配列キー、オブジェクトのプロパティに使え、欠けている最初の部分で文句を言わずに止まります。

この確認はissetと同じものなので、存在していても値がnullのキーは既定値になります。

??を連鎖させて複数の候補を試す

??は右結合で、いくつでも連鎖させられます。PHPは、設定されていてnullでない最初のオペランドを返します。

??=はnullのときだけ代入する

$a ??= $bは、$aが未設定かnullのときだけ$bを$aに格納します。既定値を埋めたり、何かを一度だけ計算して使い回したりするいちばん短い方法です。

??=の右辺は代入が行われるときだけ評価されるので、computing 4は1回しか表示されません。

??と?:(省略形の三項演算子)の違い

??はnullかどうかを、?:はtrueと評価されるかどうかを調べます。0、""、"0"のような値では答えが変わります。

"0"という数量は正当な入力です。??はそれを残し、?:は置き換えます。?:だけでは存在しないキーについて警告が出るので、このブロックでは($inputs[$key] ?? null) ?: ...のように包んでいます。?:自体については三項演算子のページで扱っています。

nullsafe演算子?->

?->は同じ考え方のオブジェクト版で、PHP 8で追加されました。左側のオブジェクトがnullなら連鎖全体がそこで止まり、Call to a member function getAddress() on nullのようなErrorを投げる代わりにnullを返します。既定値には最後に??を付けます。

ユーザー2は存在しますが住所がなく、ユーザー3はそもそも存在しません。どちらもエラーなしで?? "unknown"の既定値にたどり着きます。

よくあるミス:??は優先順位が低い

??は.や算術演算子より結びつきが弱いです。そのため"Count: " . $count ?? 0では、PHPはまず"Count: " . $countという文字列を作り、それは決してnullにならないので、既定値は使われません。

??の式がより大きな式の中にあるときは、必ず括弧で囲みましょう。

よくある質問

PHPの??はどういう意味ですか?

??はnull合体演算子です。$a ?? $bは、$aが存在してnullでなければ$aを、そうでなければ$bを返します。isset($a) ? $a : $bの短縮形で、$aや配列キーが未定義でも警告を出しません。

PHPの??と?:の違いは何ですか?

??は左辺がnullか未設定のときだけ代わりの値を使うので、0 ?? 5は0、'' ?? 'x'は''です。?:は左辺がfalseと評価されれば代わりの値を使うので、0 ?: 5は5です。また?:は未定義の変数やキーについて警告を出しますが、??は出しません。

PHPの??=は何をしますか?

$a ??= $bは、$aがnullか未設定のときだけ$bを$aに代入し、そうでなければ$aをそのままにします。$a = $a ?? $b;の短縮形で、PHP 7.4で追加されました。

PHPのnullsafe演算子?->とは何ですか?

$obj?->method()は、$objがnullでないときだけメソッドを呼び出します。nullなら、エラーを投げる代わりに連鎖全体がnullを返します。既定値には??と組み合わせます:$user?->getAddress()?->city ?? 'unknown'。PHP 8.0で追加されました。

Coddyのプログラミング言語のイラスト

Coddyでコードを学ぼう

始める