あっぽログ
← 記事一覧に戻る

PHPのMatch式を使いこなす:switch文との違いと実践的な活用パターン

match式とは

PHP8.0で導入されたmatch式は、switch文の進化版とも言える制御構文です。見た目は似ていますが、いくつかの重要な違いがあります。

<?php

$status = 2;

$label = match($status) {
    1 => '下書き',
    2 => '公開中',
    3 => '非公開',
    default => '不明',
};

echo $label; // 公開中

matchであるため、値を返します。結果を変数に代入したり、そのまま関数の引数として渡したりできます。


switch文とmatch式の違い

1. 厳密比較(===)を使う

switch文は==(緩やかな比較)を使いますが、match式は===(厳密な比較)を使います。

<?php

$value = '1'; // 文字列の '1'

// switch では true になってしまう
switch ($value) {
    case 1:
        echo 'switch: 一致した'; // ← これが実行される(危険!)
        break;
}

// match では型も含めて比較するので一致しない
$result = match($value) {
    1      => 'int の 1',
    '1'    => '文字列の 1', // ← こちらが一致する
    default => '一致なし',
};

echo $result; // 文字列の 1

この挙動の違いは、思わぬバグを防ぐうえで非常に重要です。

2. breakが不要

switchでは各casebreakを書き忘れると、次のcaseに処理がフォールスルーしてしまいます。match式ではフォールスルーはなく、breakも必要ありません。

3. defaultがない場合に例外を投げる

switchではdefaultがない場合、何も処理されずに終わります。一方match式は、どのアームにも一致しなかった場合に\UnhandledMatchErrorが投げられます。

<?php

$code = 99;

try {
    $message = match($code) {
        200 => 'OK',
        404 => 'Not Found',
        500 => 'Internal Server Error',
    };
} catch (\UnhandledMatchError $e) {
    echo '対応していないコードです: ' . $code;
    // 対応していないコードです: 99
}

これにより、考慮漏れのケースを明示的にハンドリングできます。


実践的な活用パターン

複数の値を1つのアームにまとめる

カンマ区切りで複数の値を同じアームに割り当てられます。

<?php

$day = 'Saturday';

$type = match($day) {
    'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday' => '平日',
    'Saturday', 'Sunday' => '休日',
    default => '不明',
};

echo $type; // 休日

条件式と組み合わせる(no-match with true)

match(true)を使うと、条件式をアームとして記述できます。

<?php

$score = 75;

$grade = match(true) {
    $score >= 90 => 'S',
    $score >= 80 => 'A',
    $score >= 70 => 'B',
    $score >= 60 => 'C',
    default      => 'D',
};

echo $grade; // B

if-elseifのチェーンをすっきりと書き直せるパターンです。

Enumとの組み合わせ(PHP8.1以降)

PHP8.1で導入されたEnumと組み合わせると、より型安全なコードが書けます。

<?php

enum Color
{
    case Red;
    case Green;
    case Blue;
}

$color = Color::Green;

$hex = match($color) {
    Color::Red   => '#FF0000',
    Color::Green => '#00FF00',
    Color::Blue  => '#0000FF',
};

echo $hex; // #00FF00

Enumのすべてのケースを網羅していればdefaultが不要になり、将来ケースが追加されたときにUnhandledMatchErrorで気づくことができます。

関数の戻り値として直接使う

matchは式なので、returnと組み合わせてメソッド内で直接返すことができます。

<?php

function getHttpMessage(int $code): string
{
    return match($code) {
        200 => 'OK',
        201 => 'Created',
        400 => 'Bad Request',
        401 => 'Unauthorized',
        403 => 'Forbidden',
        404 => 'Not Found',
        500 => 'Internal Server Error',
        default => 'Unknown Status',
    };
}

echo getHttpMessage(403); // Forbidden

match式を使うべき場面のまとめ

状況推奨
値を返したいmatch
型の厳密な比較が必要match
考慮漏れを例外で検知したいmatch
複雑な処理ブロックが必要switch
PHP7以前との互換性が必要switch

まとめ

match式はswitch文に比べて、厳密な比較・フォールスルーなし・式として使えるという3つの大きな利点があります。PHP8以降のコードでは積極的にmatch式を採用することで、より安全で読みやすいコードを書くことができます。

Enumとの組み合わせやmatch(true)パターンも覚えておくと、実務でのコードがぐっとすっきりします。ぜひ日々の開発に取り入れてみてください。

← 記事一覧に戻る