matchで読み易いオーバーロード(可変型非対応)

3 min read読了の目安(約3200字

php8がリリースされて約3ヶ月

Match expressionがグッと来たのでmatchの紹介を兼ねてオーバーロードの実装をします
便利なリポジトリもあるのでついでに本記事のオマケ要素としてphp8環境構築手順も載せます

https://linuxize.com/post/how-to-install-php-8-on-ubuntu-20-04/

前提

環境構築から始める人は出来ればdockerは使わずVPSホスト型[2]・ハイパーバイザー型[3]の仮想環境を用意してubuntu 20.04をインストールして使いましょう

オーバーロードの実装

コード

overload.php
declare(strict_types=1);
class Overload{
    public $field = 'PublicField';
    public function methodA(...$args){
        $f = match(count($args)){
            3 => function(string $name, int $age, string $sex): string {
                return $name.'さん、'.$age.'歳の'. $sex.'ですね。('. $this->field."も使えるよ)";
            }
            ,2 => function(string $name, string $sex): string{
                return $name.'さん、'.$sex.'ですね';
            }
            ,1 => function($name): string{
                return $name.'さん';
            }
            ,0 => function(): string {
                //defaultでの実装はNG
                return '引数無し';
            }
        };
        return $f(...$args);
    
    }
}

$ol = new Overload();
try{ echo "Ex1: ".$ol->methodA('lfz', 10, 'カマ')."\n"; }catch(\Exception $e){ echo "Ex1: Error\n"; }
try{ echo "Ex2: ".$ol->methodA('rfz', 'ネカマ')."\n";}catch(\Exception $e){ echo "Ex2: Error\n"; }
try{ echo "Ex3: ".$ol->methodA('rfz', 12)."\n";}catch(\Throwable $e){ echo "Ex3: Error\n"; }
try{ echo "Ex4: ".$ol->methodA('abc')."\n";}catch(\Exception $e){ echo "Ex4: Error\n"; }
try{ echo "Ex5: ".$ol->methodA()."\n";}catch(\Exception $e){ echo "Ex5: Error\n"; }
  • 可変型には対応しない(そこまで対応するとソース読み辛くなるのでNG
  • matchdefault使用禁止

実行

command
root@0e9a6e221dd1:/# php overload.php
Ex1: lfzさん、10歳のカマですね。(PublicFieldも使えるよ)
Ex2: rfzさん、ネカマですね
Ex3: Error
Ex4: abcさん
Ex5: 引数無し

結果

  • 引数の数に応じて用意した関数が実行された
  • 可変型には対応していないのでEx3はエラーになった

環境構築

コンテナ用意

  • コンテナをデタッチモードで起動
PowerShell7
docker run --name phptest -it -d ubuntu:20.04
  • コンテナにIN
PowerShell7
docker exec -it phptest bash

phpインストール

command
root@0e9a6e221dd1:/# apt update && apt upgrade
root@0e9a6e221dd1:/# apt install software-properties-common 
Asia(6)
Tokyo(79)
root@0e9a6e221dd1:/# add-apt-repository ppa:ondrej/php 
root@0e9a6e221dd1:/# apt update && apt upgrade && apt install -y php

php8がスタンダードになれば

matchがあればifは不要

しかし世間はまだphp7系の環境が多くmatchが当たり前な感覚になってしまうと構文エラーの時に原因が分からなくてハマってしまう事態になるので、php8が浸透するまではif不要論は勿論の事ながら構文もphp7に準拠した方が無難です[4]

脚注
  1. 真似しても上手くいかない人は諦めてphpのイメージ使いましょう ↩︎

  2. VMwareなど ↩︎

  3. Windows10 proならHyper-V ↩︎

  4. 前回の記事でサンプルコード作った際にmatch関連のエラーが分からず悩んだ ↩︎