# ch06 — 三項演算子

Source: https://php-school.pages.dev/topics/conditional/ch06-ternary/
Site: AIと学ぶPHPの学校 (https://php-school.pages.dev)
Lesson: 条件分岐
Level: L2

Reference (official): https://www.php.net/manual/ja/language.control-structures.php

## 本文

# ch06 — 三項演算子

## 概要

`if / else` の 2 分岐を **1 行・1 つの式** で書ける短縮記法が三項演算子 `(条件) ? 真の値 : 偽の値` だ。「変数に入れる値を 2 択で決めたい」「関数の引数に渡す値を条件で切り替えたい」のように、文ではなく **値が欲しい** 場面で活躍する。たとえば `$label = $score >= 60 ? "合格" : "不合格";` のように書けば、`if / else` を 4 行使わずに 1 行で済む。

PHP 7 で追加された **Null 合体演算子 `??`** は、三項演算子と似て非なるもの。`$a ?? $b` は「`$a` が `null` または **未定義** なら `$b`、それ以外なら `$a`」を返す。`$_GET['name'] ?? 'guest'` のように、配列キーが存在するかどうかをチェックしつつデフォルト値を当てたいときに便利で、三項演算子 + `isset()` の組み合わせを置き換える定番イディオムだ。「`null` のときだけ代替値」なのか「`falsy` 全般で代替値」なのかで `??` と `?:` を使い分ける。

便利な一方、三項演算子を **ネストしすぎると一気に読めなくなる** のが落とし穴。`$a ? $b : $c ? $d : $e` のように連鎖させると、PHP の評価順序の歴史的経緯もあって挙動を読み違えやすい (PHP 8 ではネストに括弧必須に変更された)。2 階層以上ネストしそうになったら、素直に `if / elseif` か `match` 式に戻す方が結果的に読みやすい。**短く書ける ≠ 良いコード** を肝に銘じる章。

## 学習目標

- `(条件) ? 真の値 : 偽の値` で if/else を 1 行に書ける
- 値を 2 択で選ぶ場面で三項演算子を使い分けられる
- 三項演算子の **使いすぎは可読性を下げる** ことを意識する

## 所要時間

スライド 4 分 + ドリル 2 問 = **12 分**

## ドリル

| no | 内容 |
|---|---|
| 01 | 点数で合格/不合格を 1 行で判定 |
| 02 | 整数の絶対値を `?:` で求める |

## 採点

```bash
php scripts/grade.php topics/conditional/ch06-ternary/drill/01-pass-fail/
```

## 関連チャプター

- [`ch02-if-else`](../ch02-if-else/) — 三項演算子の元になる `if / else` の基本形
- [`ch03-comparison`](../ch03-comparison/) — 三項演算子の条件部に置く比較式
- [`ch05-switch`](../ch05-switch/) — 多分岐は三項のネストではなく `switch` / `match` で

## スライド

---
marp: true
theme: dojo
paginate: true
size: 16:9
---

<!--
LLM_CONTEXT:
  Lesson 2 / Chapter 6
  目的: 三項演算子 (条件) ? A : B で if/else を 1 行に書けるようにする
  扱わない: null 合体演算子 ?? / Elvis 演算子 ?: (短縮形)
  読み上げ時間目安: 4 分
-->

# 三項演算子

Lesson 2 / Chapter 6

---

## if/else を 1 行で書きたい

「条件で **値を 2 択** から選ぶ」だけのとき、if/else だと冗長:

```php
<?php
if ($n >= 60) {
    $result = "合格";
} else {
    $result = "不合格";
}
echo $result . "\n";
```

これを **1 行** で書けるのが **三項演算子**。

---

## `(条件) ? 真の値 : 偽の値`

```php
<?php
$result = ($n >= 60) ? "合格" : "不合格";
echo $result . "\n";
```

- `?` の前 = 条件式
- `?` の後 = **真のときの値**
- `:` の後 = **偽のときの値**
- 全体が **1 つの値** になる → 変数に代入できる

if/else と同じ動きをコンパクトに書ける。

---

## echo の中に直接書ける

```php
<?php
echo (($n >= 60) ? "合格" : "不合格") . "\n";
```

- 三項演算子の結果は **値** なので、`echo` や文字列連結にそのまま使える
- 全体を `( )` で囲むと演算順序が明確になる

---

## ネストはしない

```php
<?php
// 動くが読みにくい (非推奨)
$s = ($n >= 80) ? "A" : (($n >= 60) ? "B" : "C");
```

- 三項演算子の中に三項演算子を入れると **一瞬で読めなくなる**
- ネストしたくなったら **素直に if/elseif/else を使う**
- 三項演算子は「**2 択** を 1 行で」のときだけ

---

## 使いどころのまとめ

| シーン | 使うべき |
|---|---|
| 値を 2 択から選ぶだけ | **三項演算子** |
| 条件で複数の処理を実行する | **if/else** |
| 3 つ以上の分岐 | **if/elseif** or **switch** |

「**短く書ける** = 偉い」ではない。
**読みやすさ** を優先する。

---

## このチャプターでできるようになること

✅ `(条件) ? A : B` で値を 2 択で選べる
✅ 三項演算子の結果を変数代入・echo に使える
✅ ネストせず、適切な場面で使い分けられる

→ ドリルへ
