PHP 入門

PHP 三項演算子とNull合体演算子

PHP における三項演算子(Ternary Operator)は、条件付き代入やエクスプレッション(式)において非常に簡潔なシンタックスを提供し、基本的な if-else 文のコンパクトな代替案となります。1 行のコードで条件を評価し、真(true)か偽(false)かに基づいて 2 つの値のうち 1 つをリターンします。

単純な二者択一の選択を処理する場合、このオペレータ(演算子)を使用してバリアブル(変数)に値を代入することは極めて効率的です。コードのリーダビリティ(可読性)を向上させ、フルセットの if-else ブロックによる冗長さを大幅に削減できます。

1. 三項演算子の基礎構文と使い方

三項演算子の基礎的な構文は以下の通りです。
条件 ? 真の場合の戻り値 : 偽の場合の戻り値;

  • 条件 (condition): 最終的な評価結果が true または false になるエクスプレッションです。
  • 真の場合の戻り値 (value_if_true): 条件が true の場合、エクスプレッション全体がこの値を返します。
  • 偽の場合の戻り値 (value_if_false): 条件が false の場合、エクスプレッション全体がこの値を返します。

ユーザーの年齢に基づいてステータスを決定するシナリオを想定します。

<?php
$age = 20;
$status = ($age >= 18) ? "成人" : "未成年";
echo "ステータス:" . $status; // 出力:ステータス:成人
echo "<br>";

$age = 16;
$status = ($age >= 18) ? "成人" : "未成年";
echo "ステータス:" . $status; // 出力:ステータス:未成年
?>

この例では、$age が 18 以上であれば $status に "成人" が代入され、そうでなければ "未成年" が代入されます。これは以下の冗長な if-else 文と同じ結果をもたらしますが、記述ははるかにコンパクトです。

<?php
$age = 20;
$status = "";

if ($age >= 18) {
    $status = "成人";
} else {
    $status = "未成年";
}

echo "ステータス (if-else 版):" . $status; // 出力:ステータス (if-else 版):成人
?>

1.1 デフォルト値の割り当て

三項演算子は、バリアブルが空(empty)であったり未定義である可能性がある場合に、デフォルト値を割り当てる際にも非常に有効です。例えば、フォームから送信された値を取得し、ユーザーが未入力だった場合にデフォルト値を使用するケースです。

<?php
// フォーム入力をシミュレート(通常は $_GET や $_POST から取得)
$usernameInput = "john_doe";

// 三項演算子を使用し、$usernameInput が空であればデフォルト値を割り当てる
$displayUsername = !empty($usernameInput) ? $usernameInput : "ゲスト";
echo "ようこそ、" . $displayUsername; // 出力:ようこそ、john_doe
echo "<br>";

$usernameInput = ""; // フォームのフィールドが空の場合をシミュレート
$displayUsername = !empty($usernameInput) ? $usernameInput : "ゲスト";
echo "ようこそ、" . $displayUsername; // 出力:ようこそ、ゲスト
?>

ここでは !empty($usernameInput) でバリアブルに内容があるかをチェックしています。内容があれば $displayUsername$usernameInput の値を取得し、そうでなければデフォルトで "ゲスト" になります。この手法は Web 開発において、オプショナルなユーザー入力を処理する際に非常に一般的です。

2. Null合体演算子 (PHP 7+ 導入)

PHP 7 では、三項演算子の特殊な形式である Null合体演算子 (??) が導入されました。これはバリアブルがセットされており、かつ NULL ではないかをチェックするために特化しています。バリアブルが NULL または未定義である可能性がある場合、三項演算子よりもさらに簡潔にデフォルト値を割り当てることができます。

構文: チェックするエクスプレッション ?? デフォルト値;
これは以下と同等です: isset(チェックするエクスプレッション) ? チェックするエクスプレッション : デフォルト値;

データベースや設定アレイ(配列)からユーザーのプリファレンスを取得するシーンを想像してください。

<?php
// ユーザー設定の取得をシミュレート
$userPreferences = [
    'theme' => 'dark',
    // 注意:ここでは 'language' キーが欠落しています
];

// Null合体演算子を使用してデフォルト言語を取得
$language = $userPreferences['language'] ?? 'ja-JP';
echo "ユーザー言語:" . $language; // 出力:ユーザー言語:ja-JP
echo "<br>";

$userPreferences2 = [
    'theme' => 'light',
    'language' => 'en',
];
$language = $userPreferences2['language'] ?? 'ja-JP';
echo "ユーザー言語:" . $language; // 出力:ユーザー言語:en
?>

この例では、$userPreferences['language']NULL であるか、あるいはキー自体が存在しない場合、$language はデフォルトで 'ja-JP' に設定されます。値が存在し NULL でなければ、その値がそのまま使用されます。欠落している可能性のあるアレイキーや、NULL になり得るバリアブルを扱う際の強力なツールです。

2.1 Null合体演算子のチェイン

複数の Null 合体演算子を連結(チェイン)して、複数の値を順番にチェックすることも可能です。

<?php
$param1 = null;
$param2 = "param2 からの値";
$param3 = "param3 からの値";

// $param1、$param2、$param3 を順にチェックし、最初の null ではない値を代入
$finalValue = $param1 ?? $param2 ?? $param3 ?? "最終的なデフォルトの代替値";
echo "最終値:" . $finalValue; // 出力:最終値:param2 からの値
?>

このチェインは左から右へと評価され、定義済みかつ NULL ではない最初の値を代入します。すべてが NULL の場合は、最後にあるデフォルト値が使用されます。

3. 三項演算子 vs. if-else 文

三項演算子は簡潔ですが、完全に if-else 文を置き換えるものではありません。

  • 簡潔性: 最大のメリットは、単純な条件付き代入を短縮し、コードの行数を減らせる点です。
  • リーダビリティ: 非常に単純な条件であれば、可読性が向上します。しかし、複雑な条件や複数の三項演算子のネスト(入れ子)は、if-else 文の明確な構造に比べて読みにくくなる傾向があります。三項演算子のネストは強く非推奨です!
  • サイドエフェクト(副作用): 三項演算子はエクスプレッション(式)であり、最終的に一つの「値」として評価されます。一方、if-else 文はコントロールストラクチャ(制御構造)であり、出力処理、複数のバリアブルの修正、複雑なファンクションの呼び出しなど、サイドエフェクトを伴う複数のステートメントを含むことができます。

要約: 条件に基づいて「値を選択する」場合は三項演算子を使用し、条件に基づいて「異なるコードブロックを実行する」場合は if-else を使用しましょう。

4. 実戦ケース

4.1 ケース 1:HTML クラス名とテキストのダイナミックレンダリング

ビューのテンプレートにおいて、条件に応じて HTML 属性を出力するのは極めて一般的です。

<?php
$isProductAvailable = true;

// 1行のコードでボタンのテキストを決定
$buttonText = $isProductAvailable ? "カートに入れる" : "一時在庫切れ";

// 1行のコードでボタンの CSS クラスを決定
$buttonClass = $isProductAvailable ? "btn-primary" : "btn-secondary disabled";

echo "<button class='" . $buttonClass . "'>" . $buttonText . "</button>";
// $isProductAvailable が true の時の出力: <button class='btn-primary'>カートに入れる</button>
?>

4.2 ケース 2:フォームのセレクトボックスにおけるデフォルトの選択状態

ユーザーの設定ページなどで、現在の設定に基づきドロップダウンメニューの特定のオプションをあらかじめ選択(selected)状態にしたい場合があります。

<?php
$userSelectedTheme = 'dark'; // データベースから取得した現在のユーザー設定

echo "<select name='theme'>";
// 三項演算子を利用して HTML タグ内で 'selected' 属性を出力するかを直接決定
echo "<option value='light' " . ($userSelectedTheme == 'light' ? 'selected' : '') . ">ライトテーマ</option>";
echo "<option value='dark' " . ($userSelectedTheme == 'dark' ? 'selected' : '') . ">ダークテーマ</option>";
echo "<option value='system' " . ($userSelectedTheme == 'system' ? 'selected' : '') . ">システム設定に従う</option>";
echo "</select>";
?>

このパターンは、どのオプションをプリセットするかをスマートに制御します。各オプションごとに肥大化した if-else ブロックを書く必要がなく、PHP スクリプト内で非常にクリーンな HTML を生成できます。