PHPにパターンマッチングはないが… 作ればいいよ

PHPではいわゆるパターンマッチングはできません。

PHP 8.0で導入された[`match`式]は「ちゃんとした」パターンマッチじゃないんだって[RFC]に書いてあったよ。

うーん… 困った。そうだね、ないなら作ろう。

```php
$result = match (ing($subject, matcher: $_, matched: $m)) {
    $_(is: 'ほげ') => 'これはほげだよ',
    $_(class: DateTime::class) => "これはDateTimeだよ",
    $_([$_->a]) => "要素1 マッチしたよ! {$m->a}",
    $_([$_->a, $_->b]) => "要素2 マッチしたよ! {$m->a} {$m->b}",
    $_([$_->a, $_->b, $_->c]) => "要素3 マッチしたよ! {$m->a}, {$m->b}, {$m->c}",
    $_(['config' => ['password' => $_->pass]]) => "password = {$m->pass}",
    $_('/\A〒?(?<up>[0-9]{3})-(?<down>[0-9]{4})\z/u') => "郵便番号は{$m->up}の{$m->down}だよ！",
    $_(is_string(...)) => "これは文字列($m->value)だよ",
    $_(is_int(...)) => "これは整数($m->value)だよ",
    $_(is_float(...)) => "これは浮動小数点数($m->value)だよ",
    default => 'not matched',
};
```

## 実装したもの

 * `is:`マッチャー
     * `===` で比較するやつ
     * 普通の`match`の条件節と同じだけど、PHPの`match`の仕様上普通のマッチングは使えなくなるので仕方なく用意したよ
 * `class:`マッチャー
     * `instanceof`でチェックするやつ
 * 配列マッチャー
     * 配列の要素が一致しているかをチェックするやつ
     * 配列の中身から値をとりたいときは`$_->hoge`みたいに書くよ
         * マッチした後から`$m->hoge`でとれるよ
     * 入れ子になっても動くよ
 * 正規表現マッチャー
     * 文字列を[`preg_match`](https://www.php.net/preg_match)でマッチさせるよ
         * マッチした内容は`$m->`でとれるよ

## 実装してないもの

 * 配列の残りの部分をぐいってまとめてとってくるやつとか
 * オブジェクトのプロパティを解体するやつとか
 * その他いろいろ

ちゃんとしたパターンマッチって何…？ うん、よくわかんない。

## コードはどこにあるの

ここにあります。説明は飽きたので各自コードを読んでください。

https://php-play.dev/?c=DwfgDgFmBQ0PQCoHQAQJQYQPZgJ4CcBLAcwgBcUAKDAShQFUBlAQQFkBJFAaQFMA7MgEMUwIQBMAzoL4ABAF5Y%2BAVwB0AWx4A%2BVMjQoZAG0IBjfhJ4oAcgE1GAGRTkyYCQC44cAO7eVAazWKWBIqfDxkcHy4EgZwOvpGpnzmKADqACoAYgAKDk5g7l4%2BnmQAZmAGIWFwZAAe4cY4uIR8xLFosdAlzYIGKPg8gmKKBrgoxgaCEhIoWROmEFgGYjz4KADeqChbYEoARgkoJUp8xmSEiigA%2BpcNSWT4SqeUO-smKBL3zcQoACR8gho6GsAL7QUHQcaTaasQRkYwQFbrTbbIgAN1hFkE%2BHwglGP2MgjAZCU-TEAG4UGA0RiUFicXiCUSSTwJGTkZS9gcjiczhdrrcPg8nlTCOiyBY1IQajwxL8JHsAFY8U5A0Fbbact7c07nPhXS7NVFYXw8SiS6Wyn5gWHi-B6gC8KGUBgMABoUCBBV9fpCpihHc63ShzTLfoRpgGlC6aK4ULssIskerk79%2BvKDBRHSUeuY2Sn1YQSlRw5cvS1KPiJlMaED2fmtoWqD801HMygS4IK2QIOGALSaeW7JWnd2VqHu%2B5KHg1pP1uc-bt9zSM4mkgDaAHJfRINwBdf0%2Bqusuv1tWnlA8AzmRuUDvY3EV61kW18GcbOfJm-Nlmtg9qWHwpcdIPguPYSP2g7DmQo5Pi%2Bo4rsyYhvieH6-Iu4HLoSq6ho6%2BJYYheaoSgZ75sCF5XjwN4lmWxCPjaKyvrWRHtkWFYthmB7UZ85agUukHKmQdAAGRCZS-TEJc-5whAdHPgxo7oRBioCaOUnwjKyHMcmvEYQhpIHj8akIuSKEpiRZnkderFWvRdrtnc0imFgRYYAYQTMkxRFfuxbY2XJdpdmBSlDgJmlaVsOn9npMqbuiBhTnuBmKQOymnIRqHmcmZGXlZTY%2BUlQUpSFpz%2BvauHhp5qGRZhTLrhu4aJeVx5zuCc79KuerfumZDpcRsDJi8XLHDqfKXMQYS3gIAA%2BNG-P8gKxiGsrvvW7Ukp1yXRWIa5-ACPD7iAIBUKZ2mbfhaY7fN%2B0eiAAY8J4MxzDwCxLCsFZXTQpk0L1oLgnh5gRiga7spugDeDIASgwbu6G6AK4MgAyDFDKAboALgyABEMe6uiDACM7oAEzugAzLumPJmuOMoLjxPY1TpNbooXTEBu-qaEDG7WlMnhYPgYhM-aLMbgs42Czwe40%2BqG6AEgMAAMADsBO9lLWMAGwE1D7KhA9AAiGJpIQGiUDQJPixDavJij6NG1sWO4wTAAsACslsoNbKh25ju5sp0XMDPCTYEgDtLTP906zls4ofBW-vTmy4Laryerh2QFb8Sqoepj%2BHGOkZxY8Sn0HBgBCL4LGPyXO6RkyiXahhfmpe3m4SMm3QfNI4AygyADEMgD2DBDgAGDBbpl19usba%2BKusaK4rjbs3LMAEQd53I88GPPB9zPTvaZclA7Zc-aCLu08oDPgCBkYABL5YyggB7DIAwwyAIMMgDqDIA%2BgyowAhOshm78Ca8D5v2%2B76OO%2BaF2PvZmh9T640vrfR%2BL835qA-jA-suxP7r3VHXX%2BmhBD-wQZg5cwCW7HxPgTCB98n6vzWO-dBwJ3RkNgYAyh8DlxIO-lvOmfAGa8xZpudmEhObc3Yb8ABXDdy4NnlwnhspHTUP7Fwxh85N4bjgAAHWYBLEAlAQDACUGATQa4pa9gAJy7jWATYENBexqOAEMTwfBtG6IMWsW2JiFFyDgEoDcB8Z6AFeEwA-fKACtXQA78qd0kZoTRwJAB2DEEyxfBgR90AID-X9ZH11LNxWiKhUkzjwfPQA4aaAHVtQA6EoVhoXFKcNBV7IIipvEszQk6pJUOk2e89AAupoAB1MCn9iKdOUpTCSwlDcrCSgNS6mH3noAO1tACrSoAeB0mmAE6HFp5D2klNRvE%2Bsyxsy-hbhuPgWAKAVx5k7YEvVlQLBQAqCQihLj8AaMsZOqV84AClGAAHlLCXHoJYAAoowDAzAshvM1i8yw7AMAPM1m810hskYgMRuifAlwxBKDUGANiGdBLuiyAACSyJcN5Dy7Ax1gHHXU9laJLTlDc8uUpQxCUMoXFY5KLQoCpTsmMKBJwWBWhFCuqw7oPRhNJN6Pw87fXZNSvl4jfics9smNadlWV4s6MNeOBdpJAXvLgM0FLLR5zpaGPycEnRRl6FSrazL4yLGgOyliVBn53npNc4qglKopmlXqbMFEfrshvA0Y4ScBU3LoCzL1AhZIvhrk6sI61Dg5h4O64VOyDyyuFdFG40gxCEDEBiQGa4PbshKN7QQvtg0MUDmGEBVpHWfmsmAeyHxHI8GcigXl6l8DlvrB4J0CYYAtUspRSt1ahAnDrUWWY%2BbnqLGWM2tOc4bzWqmBNX19qdqEH3i2qqcasxRt6sxXY-RBC%2BE3aeE6KCk0Ej4Km9N4cdpgH7FdfcuE86LuzV2nKParXhnMD6%2B9Pwl2hvnGuyNbrD1bG3QMPdplsoUSohIFVtqy0rpTF1NZSrALATVfOqCD6YLwUJEhSVXlWLPwQxmODv6aVitdbmQDKZgO7v3aRSjeFao8GTaetNGaDwockiscakdzpMZPWejNWGwA4bA92r8n6l0oGfmVX4YBiMoL-eR6NlHqOgZauyVqBZrJMsnUe3jYqGPYWYwJ8OMapXhrsiK9SsoRI%2Bn03ioAA&v=8.3&f=console

ライセンスは[NYSL](https://www.kmonos.net/nysl/)と[WTFPL](http://www.wtfpl.net/txt/copying/)のデュアルライセンスです。自由に改造して遊んでね。

## このコードがどうして動くのかわからないんだけど

[PHPのリファレンス(参照&)の傾向と対策、あるいはさよなら](https://qiita.com/tadsan/items/74f992dcc48216b571bd)を読んでください。

https://qiita.com/tadsan/items/74f992dcc48216b571bd

## なんでこんな記事を…？

[PHPのパターンマッチで遊んでみた](https://qiita.com/mnishiguchi/items/07ce4a76d9bdd83f21fb)に影響を受けました。

https://qiita.com/mnishiguchi/items/07ce4a76d9bdd83f21fb

### 出来心でやってみたくなった縛りゲーシリーズ

 * [PHPの無名関数式とは何か、そしてPHP7.4のアロー関数にそなえよう #PHP - Qiita](https://qiita.com/tadsan/items/b2a37d1a7fed1b5b2cb1)
 
 アロー関数で無名再帰して書いたスターリンソート
 
https://3v4l.org/DLuFT

そろそろ寝ます。おやすみなさい。

[`match`式]: https://www.php.net/match
[RFC]: https://wiki.php.net/rfc/match_expression_v2