ツイート
シェア
LINEで送る
B! はてぶでブックマーク
Pocketでブックマーク
RSSフィード

PHP8, match式の追加。switchとちがって変数に代入可。

php
イラストダウンロードサイト【イラストAC】
の画像をもとに加工しています。

メジャーアップデートされたPHP8.0では、新しい処理分岐の式、matchが追加されました。

もともとswitch文がありますが、ちがいは結果を返すこと。戻り値として使えるし、そうなら当然、変数に結果を代入することもできます。

switchは『文』にたいしてmatchは『式』だからできること。

match式の使い方

match式はswitch文と似ていてかんたんなので、いきなりサンプルコードから行きましょう。

$val = 100;

$ret = match ($val) {
    1    => 'one digits',
    10   => 'two digits',
    100  => 'triple digits',
    1000 => 'quadruple digits',
};

var_dump($ret);
実行結果
string(13) "triple digits"

これと同じことをswitch文で書くとこうなります。

$val = 100;

$ret = '';
switch ($val) {
    case 1:
        $ret = 'one digits';
        break;
    case 10:
        $ret = 'two digits';
        break;
    case 100:
        $ret = 'triple digits';
        break;
    case 1000:
        $ret = 'quadruple digits';
        break;
}

var_dump($ret);
実行結果
string(13) "triple digits"

matchのほうがスッキリとしていいですね?

この2つのちがいをひとつひとつ見ていきましょう。

式と文のちがい

この2つのいちばんの違いは、switchは『文』に対して matchは『式』であることです。

文は中に複数の式や文を入れて処理を書けます。だからswitchでは各条件内に処理を書いて最後にbreak構文で終わってる。

一方、matchは式なので比較に一致したときの処理は書けません。書けるのは値のみ。

そこは文ではない証拠。switch文では条件に一致したときに複数の式が書け、処理が行なえます。

文は中かっこ({})でくくればそれで終わりですが、matchは式なので最後にセミコロン(;)が必要です。

'}' と '};' で終わり方がちがうところに注意。

当然ですが、matchは式なので変数に代入することができ、関数のパラメータ、戻り値にも指定できます。

$val = 10;

function test($match)
{
    var_dump($match);
}

// パラメータに直接match式が渡せる
test(
    match ($val) {
        1    => 'one digits',
        10   => 'two digits',
        100  => 'triple digits',
        1000 => 'quadruple digits',
    }
);
実行結果
string(10) "two digits"
function test($val)
{
    // returnに直接match式が書ける
    return match ($val) {
        1    => 'one digits',
        10   => 'two digits',
        100  => 'triple digits',
        1000 => 'quadruple digits',
    };
}

$val = test(1000);
var_dump($val);
実行結果
string(16) "quadruple digits"

switch文とのちがい。値の比較は厳密。

ここがswitchとmatchの最大のちがいと言ってもいいかもしれません。

switch文の値の比較はゆるい(==)ですが、match式は型と値で厳密に(===)比較します。

PHP8になってから、ほかのところでも比較の厳密化が進んでいますが、その一貫でしょう。

match式とswitch文を実行してみましょう。

match式の比較(厳密)

<?php

function match_test($val)
{
    // returnに直接match式が書ける
    return match ($val) {
        1    => 'one digits',
        10   => 'two digits',
        100  => 'triple digits',
        1000 => 'quadruple digits',
    };
}

$val = match_test(100);
var_dump($val);

$val = match_test('100');
var_dump($val);
実行結果
string(13) "triple digits"
PHP Fatal error:  Uncaught UnhandledMatchError: Unhandled match value of type string in /home/vagrant/php-test.php:6
Stack trace:
#0 /home/vagrant/php-test.php(17): match_test()
#1 {main}
  thrown in /home/vagrant/php-test.php on line 6

match式では、値が一致しないとき黙ってスルーはしません。UnhandledMatchErrorの例外が発生します。

サンプルでは『文字列値のマッチはハンドルされていない。』のメッセージが出てますがひとつじゃないので注意が必要。

たとえば次の不一致ではメッセージがちがいます。

<?php

function match_test($val)
{
    // returnに直接match式が書ける
    return match ($val) {
        1    => 'one digits',
        10   => 'two digits',
        100  => 'triple digits',
        1000 => 'quadruple digits',
    };
}

$val = match_test(53);
var_dump($val);
実行結果
PHP Fatal error:  Uncaught UnhandledMatchError: Unhandled match value of type int in /home/vagrant/php-test.php:6
Stack trace:
#0 /home/vagrant/php-test.php(14): match_test()
#1 {main}
  thrown in /home/vagrant/php-test.php on line 6

type 〇〇のところが変わるだけなんですけどね?

switch文の比較(ゆるい)

function switch_test($val)
{
    $ret = 'value none';
    switch ($val) {
        case 1:
            $ret = 'one digits';
            break;
        case 10:
            $ret = 'two digits';
            break;
        case 100:
            $ret = 'triple digits';
            break;
        case 1000:
            $ret = 'quadruple digits';
            break;
    }
    var_dump($ret);
}

switch_test(100);
switch_test('100');
switch_test(53);
実行結果
string(13) "triple digits"
string(13) "triple digits"
string(10) "value none"

switch文は不一致であってもエラーにならずスルーされます。

match式に比べ、比較もゆるゆる、結果もゆるゆる、の曖昧さ満載です。

breakはいらない。

match式は上から順に比較していき、一致すればそこで式が終了し、そうじゃなければ次の比較を行うので、break; はいりません。

一方、switch文は、比較が一致しても次の比較を行います。だから比較の終わりには必ずbreak; を付ける慣習があるんですね?

とういか、break; を書かない理由がない。余計な処理が走るし。

そもそもbreakは文を抜けるためのキーワードです。式のmatchで使えるわけがない。

前の投稿
PHP8, 戻り値の型で使う static型ってなんだ? ネーミングがややこしくない?
PHP8, Nullsafe, オブジェクトのnullチェックを省略するプロパティ・メソッド参照
次の投稿
コメントを残す

*