if 文と条件分岐 - 基本の使い方

プログラムは上から下へ順番に実行される。しかし「条件によって処理を変えたい」場面は頻繁に発生する。if 文はそのための最も基本的な構文であり、あらゆるプログラミングの土台となる。

if 文の基本構文

if 文は条件式を評価し、その結果が true であれば中のブロックを実行する。

$age = 20;

if ($age >= 18) {
    echo "成人です";
}

条件式 age >= 18` が true なので、`echo "成人です"` が実行される。条件が false の場合、ブロック内の処理はスキップされる。 PHP では条件式を囲む丸括弧 `()` が必須であり、省略するとシンタックスエラーになる。波括弧 `{}` は文が 1 つだけなら省略できるが、可読性のために常に書くのが推奨される。 ## else による二択分岐 条件が false だった場合にも処理を行いたいときは else を使う。 <!-- outer_1 --> この構造は「どちらか一方が必ず実行される」という二択の分岐を表現する。else ブロックに条件式は書かない。 <!-- outer_2 --> ## elseif で多段分岐 条件が 3 つ以上に分かれる場合は elseif を使う。PHP では `elseif` と `else if`(スペースあり)のどちらも使えるが、`elseif` が推奨されている。 <!-- outer_3 --> elseif は上から順に評価され、最初に true になった条件のブロックだけが実行される。`score が 75 の場合、最初の score >= 70 が true なので score >= 50 が最初に true になるため、常に “C” が返ってしまう。より厳しい条件を先に書くのが鉄則である。

条件式と型の扱い

PHP の if 文は条件式を boolean として評価する。boolean 以外の値が渡された場合、PHP の型変換ルールに従って自動的に true か false に変換される。

false と評価される値

false00.0、空文字列 ""、文字列 "0"、空配列 []null が false として扱われる。これらは falsy な値と呼ばれる。

true と評価される値

上記以外はすべて true になる。"0" は false だが " "(スペース)や "false" は true である点に注意が必要だ。

この暗黙の型変換は便利な反面、予期しないバグの原因にもなる。

$name = "";

if ($name) {
    echo "名前があります";
} else {
    echo "名前が空です"; // こちらが実行される
}

空文字列は false として評価されるため、このコードは動作する。しかし意図を明確にするなら name) > 0 のように明示的に書くほうが安全である。

比較演算子

条件式では比較演算子を使って値を比較する。PHP には「緩い比較」と「厳密な比較」の 2 種類がある。

演算子意味種類
==値が等しい緩い比較
===値と型が等しい厳密な比較
!=値が等しくない緩い比較
!==値または型が異なる厳密な比較
var_dump(0 == "foo");   // true(PHP 7 以前)
var_dump(0 === "foo");  // false
var_dump("" == null);   // true
var_dump("" === null);  // false

緩い比較 == は型変換を行ってから比較するため、直感に反する結果を生むことがある。PHP 8.0 で 0 == "foo" は false に変更されたが、それでも === を使う習慣をつけたほうが安全だ。

次のうち、PHP 8 で true を返すのはどれですか?

  • 0 == "abc"
  • "" === null
  • 0 === 0
  • null == false && null === false
__RESULT__

0 === 0 は値も型(int)も同じなので true を返します。PHP 8 では 0 == "abc" は false に変更されました。null == false は true ですが null === false は false なので、AND 条件全体は false になります。

論理演算子で条件を組み合わせる

複数の条件を組み合わせるには論理演算子を使う。

$age = 25;
$hasLicense = true;

if ($age >= 18 && $hasLicense) {
    echo "運転できます";
}

&&(AND)は両方が true のときに true を返し、||(OR)はどちらか一方が true なら true を返す。!(NOT)は真偽値を反転させる。

PHP には &&and||or の 2 組が存在するが、演算子の優先順位が異なる。&&|| のほうが優先順位が高く、代入演算子より先に評価される。一方 andor は代入より優先順位が低い。

// 意図しない動作
$result = false || true;  // $result は true
$result = false or true;  // $result は false(代入が先に評価される)

混乱を避けるため、&&|| を一貫して使うのが推奨される。

短絡評価

PHP の論理演算子は短絡評価(ショートサーキット)を行う。&& では左辺が false なら右辺を評価せず、|| では左辺が true なら右辺を評価しない。

$user = null;

if ($user !== null && $user->isActive()) {
    echo "アクティブユーザー";
}

user !== null が false になるため $user->isActive() は呼ばれない。もし短絡評価がなければ null に対してメソッドを呼び出してエラーになるところである。この性質を利用してガード条件を書くのは一般的なテクニックだ。

左辺を評価する

false なら右辺をスキップ(&&)

エラーを未然に防げる

if 文のネストと早期リターン

条件が複雑になると if 文がネストして読みにくくなることがある。

// ネストが深い例
function processOrder($order) {
    if ($order !== null) {
        if ($order->isPaid()) {
            if ($order->hasStock()) {
                return "発送します";
            } else {
                return "在庫切れ";
            }
        } else {
            return "未払い";
        }
    } else {
        return "注文がありません";
    }
}

早期リターン(ガード節)を使えば、ネストを減らして読みやすくできる。

function processOrder($order) {
    if ($order === null) {
        return "注文がありません";
    }
    if (!$order->isPaid()) {
        return "未払い";
    }
    if (!$order->hasStock()) {
        return "在庫切れ";
    }
    return "発送します";
}

異常系を先に弾いて return することで、正常系の処理がインデントなしで書ける。コードの見通しが良くなり、条件の追加・変更も容易になる。

条件分岐はプログラムの流れを制御する最も基本的な道具であり、if 文はその中核を担う。比較演算子の選択、条件の順序、ネストの回避といった細部に気を配ることで、読みやすく安全なコードを書くことができる。