PHPのnull合体演算子 ?? は、左辺の値が null でなければ左辺を、null であれば右辺を返す演算子です。PHP 7.0で導入され、isset() と三項演算子を組み合わせていた冗長なnullチェックを、1つの演算子でスッキリ書けるようになりました。
フォーム入力のデフォルト値設定、設定値の取得、APIレスポンスの処理など、nullになりうる値を安全に扱うあらゆる場面で活躍します。
基本的な使い方
PHP
<?php
$name = null;
echo ($name ?? "ゲスト") . "\n";
$name = "田中";
echo ($name ?? "ゲスト") . "\n";
// 未定義の変数にも使える(Warningが出ない)
echo ($undefinedVar ?? "デフォルト値") . "\n";
実行結果
ゲスト
田中
デフォルト値
$name が null の場合は右辺の「ゲスト」が返され、値がある場合はその値がそのまま返されます。重要な点として、未定義の変数に対しても警告なしで使えます。
issetとの比較
?? は isset() + 三項演算子の省略形です。
PHP
<?php
$data = ["name" => "田中", "age" => 30];
// 従来の書き方
$email1 = isset($data["email"]) ? $data["email"] : "未設定";
// null合体演算子(同じ結果)
$email2 = $data["email"] ?? "未設定";
echo "従来: {$email1}\n";
echo "??: {$email2}\n";
// ネストした配列でも安全
$config = ["db" => ["host" => "localhost"]];
$port = $config["db"]["port"] ?? 3306;
echo "ポート: {$port}\n";
実行結果
従来: 未設定
??: 未設定
ポート: 3306
チェーン(連続使用)
?? は連続して使えます。左から順に評価され、最初にnullでない値が返されます。
PHP
<?php
$primary = null;
$secondary = null;
$fallback = "デフォルト";
// 左から順にnullでないものを探す
echo ($primary ?? $secondary ?? $fallback) . "\n";
$secondary = "セカンダリ値";
echo ($primary ?? $secondary ?? $fallback) . "\n";
// 設定値の優先順位
$envLang = null; // 環境変数
$configLang = null; // 設定ファイル
$defaultLang = "ja"; // デフォルト
$lang = $envLang ?? $configLang ?? $defaultLang;
echo "言語: {$lang}\n";
実行結果
デフォルト
セカンダリ値
言語: ja
null合体代入演算子(??=)
PHP 7.4で追加された ??= は、変数がnullの場合にのみ代入する演算子です。
PHP
<?php
$settings = [
"theme" => "dark",
];
// nullの場合のみ代入
$settings["theme"] ??= "light"; // 既に値があるので変わらない
$settings["language"] ??= "ja"; // 未定義なので代入される
$settings["fontSize"] ??= 14; // 未定義なので代入される
print_r($settings);
実行結果
Array
(
[theme] => dark
[language] => ja
[fontSize] => 14
)
実用的な例
PHP
<?php
// フォーム入力のデフォルト値($_GETの代わりに配列で模擬)
$get = ["page" => "3"];
$page = (int)($get["page"] ?? 1);
$sort = $get["sort"] ?? "created_at";
$order = $get["order"] ?? "desc";
echo "ページ: {$page}, ソート: {$sort}, 順序: {$order}\n";
// APIレスポンスの安全な値取得
$response = [
"data" => [
"user" => [
"name" => "田中太郎",
"profile" => null,
]
]
];
$name = $response["data"]["user"]["name"] ?? "不明";
$bio = $response["data"]["user"]["profile"]["bio"] ?? "自己紹介なし";
$avatar = $response["data"]["user"]["avatar"] ?? "/img/default.png";
echo "名前: {$name}\n";
echo "自己紹介: {$bio}\n";
echo "アバター: {$avatar}\n";
実行結果
ページ: 3, ソート: created_at, 順序: desc
名前: 田中太郎
自己紹介: 自己紹介なし
アバター: /img/default.png
??と?:の違いに注意
?? は null のみをチェックします。一方、?:(Elvis演算子)は false、0、""(空文字)、null など falsy な値すべてをチェックします。0 や "" を有効な値として扱いたい場合は ?? を使いましょう。
ポイント
PHP 8.0の ?->(nullsafe演算子)と組み合わせると、さらに安全なチェーンアクセスが可能です。例えば $user?->getAddress()?->getCity() ?? "不明" のように、途中で null が返されても安全にデフォルト値を設定できます。
まとめ
??は左辺がnullでなければ左辺を、nullなら右辺を返すisset()+ 三項演算子の省略形として使える- チェーン(
$a ?? $b ?? $c)で複数の候補から最初のnull以外を取得 ??=でnullの場合のみ代入できる(PHP 7.4+)?:との違いに注意:??はnullのみ、?:はfalsyな値すべてが対象