はじめに
前回の記事で、文字列を出力する最も基本的な構文 echo を解説しました。今回取り上げる if は、それと並んでプログラミングの最も根本的な要素である「条件分岐」を実現する、PHPの制御構造です。
if 文は、指定した条件式が true と評価された場合にのみ、特定のコードブロックを実行するための構文です。else、elseif との組み合わせ、HTMLテンプレート内で読みやすくなる代替構文(Alternative Syntax)、そして現代的な三項演算子や match 式との使い分けまで、知っておくべきポイントは意外と多岐にわたります。本記事では基本的な使い方から、実践的な活用パターン、よくある落とし穴まで詳しく解説します。
構文概要
| 項目 | 内容 |
|---|---|
| 構文名 | if |
| 種別 | 制御構造(言語構文) |
| 基本構文 | if (条件式) { 処理 } |
| 関連キーワード | else、elseif(またはelse if) |
| 代替構文 | if (条件式): 処理 endif;(テンプレート内で使われることが多い) |
| 対応バージョン | PHP 4以前から存在する最古参の構文の一つ |
| 条件式の評価 | 真偽値への型変換ルール(truthy/falsy)に従って評価される |
条件分岐の流れ(イメージ図)
if ($condition1) {
// $condition1がtrueの場合のみ実行
} elseif ($condition2) {
// $condition1がfalseで$condition2がtrueの場合に実行
} else {
// どちらもfalseの場合に実行
}
│
▼
┌───────────────────────────┐
│ 上から順番に条件式を評価し、 │
│ 最初にtrueになったブロックだけが │
│ 実行される(それ以降は評価されない) │
└───────────────────────────┘
ポイントは、elseif の条件式が前の条件がすべて false だった場合にのみ評価されるという点です。これにより、複数の条件を効率よく、かつ読みやすい形で順番にチェックできます。
実践サンプル7選
例1:基本的な使い方
<?php
$age = 20;
if ($age >= 18) {
echo '成人です' . PHP_EOL;
} else {
echo '未成年です' . PHP_EOL;
}
例2:elseifを使った複数条件の分岐
<?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(85) . PHP_EOL; // "B"
例3:テンプレート内での代替構文(Alternative Syntax)の活用
<?php $isLoggedIn = true; $username = '太郎'; ?>
<div>
<?php if ($isLoggedIn): ?>
<p>ようこそ、<?= htmlspecialchars($username) ?>さん</p>
<?php else: ?>
<p>ログインしてください</p>
<?php endif; ?>
</div>
例4:truthy/falsyな値の評価に注意した実装
<?php
function describeValue(mixed $value): string
{
// 0, '0', '', null, false, 空配列はすべてfalsyとして扱われる
if ($value) {
return '値が設定されています';
}
return '値が空、ゼロ、またはfalseです';
}
echo describeValue('0') . PHP_EOL; // "値が空、ゼロ、またはfalseです"(意外と見落としやすい)
echo describeValue('hello') . PHP_EOL; // "値が設定されています"
echo describeValue([]) . PHP_EOL; // "値が空、ゼロ、またはfalseです"
例5:早期リターンによるネストの回避
<?php
class OrderValidator
{
/**
* else句を使わず、条件を満たさない場合に
* 早期リターンすることでネストを浅く保つ
*/
public function validate(?array $order): string
{
if ($order === null) {
return '注文データがありません';
}
if (empty($order['items'])) {
return '商品が選択されていません';
}
if (($order['total'] ?? 0) <= 0) {
return '合計金額が不正です';
}
return '検証に成功しました';
}
}
$validator = new OrderValidator();
echo $validator->validate(['items' => ['A'], 'total' => 1000]) . PHP_EOL;
例6:複数条件の組み合わせ(論理演算子との併用)
<?php
function canAccessAdminPanel(bool $isLoggedIn, string $role): bool
{
// &&(かつ)、||(または)を使った複合条件
if ($isLoggedIn && ($role === 'admin' || $role === 'superadmin')) {
return true;
}
return false;
}
var_dump(canAccessAdminPanel(true, 'admin')); // true
var_dump(canAccessAdminPanel(true, 'guest')); // false
var_dump(canAccessAdminPanel(false, 'admin')); // false
例7:match式との使い分けを比較するデモ(PHP 8.0以降)
<?php
function describeHttpStatusWithIf(int $code): string
{
if ($code >= 200 && $code < 300) {
return '成功';
} elseif ($code >= 400 && $code < 500) {
return 'クライアントエラー';
} elseif ($code >= 500) {
return 'サーバーエラー';
} else {
return 'その他';
}
}
function describeHttpStatusWithMatch(int $code): string
{
// 単純な値の一致判定であればmatchの方が簡潔になることもある
return match (true) {
$code >= 200 && $code < 300 => '成功',
$code >= 400 && $code < 500 => 'クライアントエラー',
$code >= 500 => 'サーバーエラー',
default => 'その他',
};
}
echo describeHttpStatusWithIf(404) . PHP_EOL;
echo describeHttpStatusWithMatch(404) . PHP_EOL;
関連機能との比較
| 機能 | 役割 | ifとの違い |
|---|---|---|
if / elseif / else | 条件に応じて処理を分岐する | 本記事の対象。最も汎用的な条件分岐構文 |
switch | 1つの値を複数のケースと比較する | 同一の値を多数の候補と比較する場合に、ifの連鎖より読みやすくなることがある |
match(PHP 8.0以降) | 値に基づいて式を返す、より厳密な分岐 | 厳密な比較(===相当)を行い、値を返す「式」である点が異なる |
三項演算子(?:) | 条件に応じて2つの値のどちらかを返す簡潔な式 | 単純な値の選択に特化しており、複雑な処理ブロックには向かない |
Null合体演算子(??) | 値がnullの場合にデフォルト値を使う | isset()を伴うifの典型的なパターンを簡潔に書ける、より限定的な構文 |
よくある落とし穴(注意点)
- truthy/falsyの評価ルールを正しく理解する
if ($value)という書き方は便利ですが、0、'0'、''(空文字列)、null、false、空配列[]がすべてfalseとして扱われる(falsy)という、PHP特有の型変換ルールを理解していないと、意図しない分岐になることがあります(例4を参照)。文字列の'0'が特にはまりやすい落とし穴です。 elseifとelse if(スペースあり)はほぼ同じだが、代替構文では注意が必要 通常の中括弧構文ではelseifとelse ifはどちらも同じように動作しますが、コロン構文(代替構文)を使う場合はelseifと1単語で書く必要があります。else ifと書くと構文エラーになるため注意しましょう。- 深いネストはコードの可読性を損なう 条件分岐が何重にもネストすると、コードが読みにくくなります。早期リターン(ガード節)のパターンを使うことで、ネストを浅く保ち、処理の流れを分かりやすくできます(例5を参照)。
- 代入と比較演算子の混同(
=と==)if ($x = 5)のように、比較演算子==の代わりに代入演算子=を誤って書いてしまうと、常に代入された値(この場合は5、truthyな値)で条件が評価されてしまいます。多くの静的解析ツールがこのミスを警告してくれますが、注意が必要です。 - 複雑な条件は、可読性のために変数や専用メソッドに切り出す
ifの条件式が長く複雑になりすぎると、何を判定しているのかが読み取りにくくなります。条件を意味のある名前の変数やメソッドに分割することで、コードの意図を明確にできます(例6のような単純な例でも、複雑化する前に分割を検討する価値があります)。
まとめ
| 観点 | まとめ |
|---|---|
| 何をする構文か | 指定した条件式がtrueの場合にのみ、特定の処理を実行する |
| 主な用途 | あらゆる条件分岐処理、バリデーション、アクセス制御判定 |
| 関連キーワード | elseif(複数条件の連鎖)、else(それ以外の場合の処理) |
| 代替構文 | HTMLテンプレート内ではif (...): ... endif;というコロン構文が読みやすい |
| 注意点 | truthy/falsyの評価ルール、深いネストの回避、=と==の混同に注意すること |
if は、PHPに限らずあらゆるプログラミング言語に共通する、最も基本的でありながら最も頻繁に使われる制御構造です。truthy/falsyの評価ルールを正しく理解し、早期リターンなどの読みやすいコードパターンを意識することで、保守しやすく意図の伝わりやすい条件分岐を書くことができます。
