はじめに
これまでの記事で、条件分岐の基本となる if と else を解説してきました。今回取り上げる elseif は、この2つを組み合わせることで、3つ以上の条件を順番に判定するための構文です。
elseif は、直前の if(または別の elseif)の条件が false だった場合にのみ評価される、追加の条件式を持つブロックです。「成績によってA〜Dのランクを判定する」「HTTPステータスコードの範囲によってメッセージを変える」といった、複数の条件を段階的にチェックする処理において非常によく使われます。本記事では基本的な使い方から、よく似た else if(スペースあり)との違い、switch/match との使い分けまで詳しく解説します。
構文概要
| 項目 | 内容 |
|---|---|
| 構文名 | elseif |
| 種別 | 制御構造(言語構文、ifと組み合わせて使用) |
| 基本構文 | if (条件1) { ... } elseif (条件2) { ... } else { ... } |
| 単独での使用 | 不可(必ずifの後に続ける必要がある) |
| 似た構文 | else if(スペースあり、中括弧構文ではelseifとほぼ同義) |
| 対応バージョン | PHP 4以前から存在する最古参の構文の一つ |
| 評価の仕組み | 前の条件がすべてfalseの場合にのみ、自身の条件式が評価される |
評価の連鎖(イメージ図)
if ($score >= 90) {
// 条件1を評価 → trueなら実行して終了
} elseif ($score >= 70) {
// 条件1がfalseの場合のみ、条件2を評価
} elseif ($score >= 50) {
// 条件1,2がfalseの場合のみ、条件3を評価
} else {
// すべての条件がfalseの場合に実行
}
│
▼
┌───────────────────────────┐
│ 上から順に評価され、 │
│ 最初にtrueになった時点で │
│ そのブロックだけが実行され、 │
│ 以降の条件は一切評価されない │
│ (ショートサーキット的な動作) │
└───────────────────────────┘
ポイントは、elseif の条件式が無条件に評価されるわけではなく、それより前のすべての条件が false だった場合にのみ評価されるという点です。これにより、無駄な評価を省きながら、複数の条件を効率よくチェックできます。
実践サンプル7選
例1:基本的な使い方
<?php
function gradeFromScore(int $score): string
{
if ($score >= 90) {
return 'A';
} elseif ($score >= 70) {
return 'B';
} elseif ($score >= 50) {
return 'C';
} else {
return 'D';
}
}
echo gradeFromScore(75) . PHP_EOL; // "B"
例2:複数の条件式を含むelseif
<?php
function describeSeason(int $month): string
{
if ($month === 12 || $month === 1 || $month === 2) {
return '冬';
} elseif ($month >= 3 && $month <= 5) {
return '春';
} elseif ($month >= 6 && $month <= 8) {
return '夏';
} elseif ($month >= 9 && $month <= 11) {
return '秋';
} else {
return '不正な月です';
}
}
echo describeSeason(4) . PHP_EOL; // "春"
例3:elseifとelse if(スペースあり)の挙動の違いを確認する
<?php
$value = 5;
// 通常の中括弧構文では、elseifとelse if(スペースあり)は同じ意味
if ($value === 1) {
echo 'one';
} elseif ($value === 5) {
echo 'five (elseif使用)' . PHP_EOL;
}
if ($value === 1) {
echo 'one';
} else if ($value === 5) {
echo 'five (else if使用)' . PHP_EOL;
}
// 中括弧構文ではどちらも同じ結果になる
例4:代替構文(コロン構文)ではelseifのみが許可される
<?php $status = 'pending'; ?>
<?php if ($status === 'completed'): ?>
<p>完了しました</p>
<?php elseif ($status === 'pending'): ?>
<p>処理中です</p>
<?php else: ?>
<p>不明なステータスです</p>
<?php endif; ?>
<!-- コロン構文では"else if"(スペースあり)は構文エラーになるため、必ず"elseif"と書く -->
例5:elseifの連鎖が長くなりすぎた場合のmatchへの書き換え
<?php
function httpStatusMessageWithElseif(int $code): string
{
if ($code === 200) {
return 'OK';
} elseif ($code === 201) {
return 'Created';
} elseif ($code === 400) {
return 'Bad Request';
} elseif ($code === 404) {
return 'Not Found';
} elseif ($code === 500) {
return 'Internal Server Error';
} else {
return 'Unknown';
}
}
/**
* 単純な値の一致判定が連続する場合、match式の方が
* 簡潔かつ厳密な比較(===相当)で書ける
*/
function httpStatusMessageWithMatch(int $code): string
{
return match ($code) {
200 => 'OK',
201 => 'Created',
400 => 'Bad Request',
404 => 'Not Found',
500 => 'Internal Server Error',
default => 'Unknown',
};
}
echo httpStatusMessageWithMatch(404) . PHP_EOL;
例6:範囲判定におけるelseifの順序の重要性
<?php
function describeTemperature(int $celsius): string
{
/**
* 条件の順序が重要: もし条件を逆順(低い方から)に書くと、
* すべての条件が意図せずマッチしてしまうバグになりやすい
*/
if ($celsius >= 30) {
return '猛暑';
} elseif ($celsius >= 25) {
return '暑い';
} elseif ($celsius >= 15) {
return '過ごしやすい';
} else {
return '寒い';
}
}
echo describeTemperature(32) . PHP_EOL; // "猛暑"(最初にマッチした条件が採用される)
例7:バリデーションルールの段階的なチェック
<?php
class PasswordValidator
{
/**
* 複数の検証ルールを、最初に失敗したものから
* 順番に報告する典型的なelseifの活用パターン
*/
public function validate(string $password): string
{
if (strlen($password) < 8) {
return '8文字以上である必要があります';
} elseif (!preg_match('/[A-Z]/', $password)) {
return '大文字を1文字以上含める必要があります';
} elseif (!preg_match('/[0-9]/', $password)) {
return '数字を1文字以上含める必要があります';
} else {
return '有効なパスワードです';
}
}
}
$validator = new PasswordValidator();
echo $validator->validate('short') . PHP_EOL;
echo $validator->validate('longenough') . PHP_EOL;
echo $validator->validate('LongEnough1') . PHP_EOL;
関連機能との比較
| 機能 | 役割 | elseifとの違い |
|---|---|---|
elseif | 前の条件がfalseの場合に、新たな条件で判定する | 本記事の対象。中括弧構文とコロン構文の両方で使える |
else if(スペースあり) | elseifとほぼ同義の書き方 | 中括弧構文では同じ動作だが、代替構文(コロン構文)では使えない |
else | 条件を持たず、「残り全部」を受け止める | 独自の条件式を持たない点がelseifと異なる |
switch | 1つの値を複数のケースと比較する | 同じ変数の値を多数の候補と比較する場合に適している |
match(PHP 8.0以降) | 値に基づいて式を返す、厳密な比較を行う分岐 | 単純な値の一致判定が連続する場合、elseifの連鎖より簡潔に書けることが多い |
よくある落とし穴(注意点)
- コロン構文(代替構文)では
else ifが使えない HTMLテンプレート内でよく使われるif (...): ... endif;という代替構文では、必ず1単語のelseifと書く必要があります。else if(スペースあり)と書くと構文エラーになります(例4を参照)。 - 条件の順序を誤ると意図しない分岐になる 範囲判定を行う
elseifの連鎖では、条件を書く順序が結果に直結します。広い範囲の条件を先に書いてしまうと、後続のより狭い条件が一生評価されない、というバグを生みやすくなります(例6を参照)。 elseifの連鎖が長くなりすぎると可読性が低下する 同じ変数に対する単純な値の一致判定をelseifで何個も連ねると、コードが縦に長くなり読みにくくなります。こうしたケースでは、match(PHP 8.0以降)やswitchへの書き換えを検討しましょう(例5を参照)。- 各
elseifブロックで異なる変数を評価すると意図が伝わりにくくなるelseifの連鎖は、本来は「同じ関心事について、条件を変えながら順番にチェックする」という用途に向いています。まったく関係のない複数の条件を無理やりelseifでつなげると、コードの意図が読み取りにくくなるため、そのような場合は個別のif文に分割することも検討しましょう。 - 最初にマッチした条件だけが実行されることを前提に設計する
elseifの連鎖では、複数の条件が同時にtrueになりうる場合でも、最初にマッチしたブロックだけが実行され、それ以降は一切評価されません。「複数の条件それぞれに対して個別に処理をしたい」という要件であれば、elseifではなく独立した複数のif文を使うべきです。
まとめ
| 観点 | まとめ |
|---|---|
| 何をする構文か | 直前のif/elseifの条件がfalseの場合にのみ、新たな条件で判定する |
| 主な用途 | 成績ランクの判定、範囲ごとのメッセージ分岐、段階的なバリデーション |
else ifとの違い | 中括弧構文では同義だが、コロン構文(代替構文)ではelseifのみが有効 |
| 条件の順序 | 範囲判定では、条件を書く順序が結果を左右するため注意が必要 |
| 注意点 | 連鎖が長くなりすぎた場合はmatch/switchへの書き換えを検討すること |
elseif は、複数の条件を段階的かつ効率的に判定するための、if–else の自然な拡張です。条件の順序に注意しながら使う一方、単純な値の一致判定が延々と続くようであれば、より簡潔に書ける match 式への切り替えも視野に入れると、より読みやすいコードを実現できます。
