【PHP】"switch"の代わりに"match式"を使おう！match式のいいところ6選

# 初めに
**こんにちは！元Javaエンジニアの駆け出しPHPerです！**

最近、PHPには**match式**なるものがあることを知りました。switchよりも便利だと感じたので、今回はmatch式についてまとめていきます。

# match式とは
PHP8.0で追加された**式**です。
switchと似たような使い方ができます。

```php
$food = 'cake';

match ($food) {
    'apple' => print 'This food is an apple',
    'bar' => print 'This food is a bar',
    'cake' => print 'This food is a cake',
};

// This food is a cake
```
https://www.php.net/manual/ja/control-structures.match.php

# match式のいいところ
続いてmatch式のいいところを紹介します。
switchと比較しながら見ていきましょう。

## 1. 式である
switchは命令であるのに対し、matchは**式**です。
そのため、**返り値を定義することができます**。

以下は、返り値を変数に代入した例です。便利ですね～～～～～！

```php
$food = 'cake';

$message = match ($food) {
    'apple' => 'This food is an apple',
    'bar' => 'This food is a bar',
    'cake' => 'This food is a cake',
};

print $message
// This food is a cake
```

## 2. 厳密比較してくれる
match式の場合、条件判定で**厳密比較**を行ってくれます。


```php
$number = '1';

print match ($number) {
    1 => 'route 1',
    default => 'default'
};
// default
```
それに対し、switchは曖昧比較で判定します。
プロダクトコードだと使いづらい、、、（PHPに慣れないJavaエンジニアにとってはなおさら）

```php
$number = '1';
switch ($number) {
    case 1:
        print 'route 1';
        break;
    
    default:
        print 'default';
        break;
}
// route 1
```

## 3. breakが不要
match式の場合、**breakが不要**です。
処理の実行後にmatch式を抜けてくれます。

```php
$number = '1';

print match ($number) {
    '1' => 'route 1',
    '1' => 'route 2',
    default => 'default'
};
// route 1
```


switchの場合、全てのcaseを比較し、当てはまる処理全てを実行してしまいます。
```php
$number = '1';

switch ($number) {
    case 1:
        print 'int 1'."\r\n";
    case "1":
        print 'String 1'."\r\n";
    default:
        print 'default';
}
// int 1
// String 1
// default
```


## 4. 条件に関数を使うことができる
match式の場合、**条件に関数やメソッドを使うことが可能**です。

```php
$number = '1';

print match (true) {
    is_null($number) => 'route 1',
    isset($number) => 'route 2',
    default => 'default'
};
// route 2
```

## 5. 条件に当てはまらない場合エラーになる

match式の場合、**全ての条件に当てはまらない場合はエラーを出してくれます**。
default句を忘れた場合など、テスト段階で気づくことができますね。

```php
$number = '99';

print match ($number) {
    '1' => 'route 1',
    '2' => 'route 2',
};

// PHP Fatal error:  Uncaught UnhandledMatchError: Unhandled match case '...' in /workspace/Main.php:5
// Stack trace:
// #0 {main}
//   thrown in /workspace/Main.php on line 5
```

switchの場合はエラー出ません。
```php
$number = '99';

switch ($number) {
    case '1':
        print 'route 1';
        break;
    case '2':
        print 'toute 2';
        break;
}

print "Exception was not throwed"
// Exception was not throwed
```

## 6. 配列との相性が良い（※2024年3月6日追記）
@R-sato0104 さんからコメントでご教示いただきました！
switchと違い、match式は配列との相性が良いです！

こんな感じで条件に配列を指定することができちゃいます。
```php
$array = ['key1' => null, 'key2' => '2'];

print match (true) {
    isset($array['key1'])  => 'route 1',
    isset($array['key2']) => 'route 2',
    default => 'default'
};
// route 2
```

式なので、こんな感じでarrayの中に書くこともできますね。
Javaのstreamと似てて既視感あります。
```php
$array = [1, 2, 3];

foreach ($array as $key => $val) {
    $array2[] = match ($val) {
        1 => 'route 1',
        2 => 'route 2',
        default => 'default'
    };
}

var_dump($array2);

// array(3) {
//  [0]=>  string(7) "route 1"
//  [1]=>  string(7) "route 2"
//  [2]=>  string(7) "default"
// }
```

# switchのいいところ
ここまでmatch式のいいところばかり紹介してきたので、最後にswitchでしかできないことも（一応）紹介しておきます。

## 1. 各ルートの処理を複数文書ける
条件に当てはまった際、処理を複数文書くことができます。
match式はあくまで"式"なので、単数文しか書くことができません。
```php
$number = '1';

switch ($number) {
    case '1':
        print 'route 1';
        print "\r\n";
        print 'pathed!!!';
        break;
    case '2':
        print 'toute 2';
        print "\r\n";
        print 'pathed!!!';
        break;
}
// route 1
// pathed!!!
```

**以上！！！**

（自分の知識がないだけなので、他にもあったら是非教えてくださいmm）

# 終わりに
今回はmatch式についてまとめました。
match式を知れたのもそうですが、なによりswitchが曖昧比較だと知れたのもよかったです。
AIで楽にプログラムが書けるようになった分、こういう知識がないとバグを生んでしまうなと感じています。Javaの感覚で書かないよう、これからも調べていこうと思いました。

また何かあればアウトプットします！
ここまで読んでいただきありがとうございました！

# 参考
* [独習PHP 第4版](https://www.amazon.co.jp/%E7%8B%AC%E7%BF%92PHP-%E7%AC%AC4%E7%89%88-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/4798168491)
* [【PHP8】match式/switch文の違いとバグの入りにくさ](https://tech-blog.rakus.co.jp/entry/20200917/php)