読者です 読者をやめる 読者になる 読者になる

B-Teck!

お仕事からゲームまで幅広く

【PHP】PHPでオーバーロードみたいなことをしたかった。

PHPは実行時に型が決まるため、オーバーロードという仕組みがない。
似たような仕組みを実装したくて色々やってみた。

↓参考
PHPでオーバーロードしたい - チキン煮込みチーズミックス4辛


PHPオーバーロードに近いことを

  • 仮引数を用意して引数の数などに応じて分岐
  • __callを使って、「PHPオーバーロード」で分岐する


__callを使うのはあんまり趣味じゃないので仮引数を使う方法にする。

<?php
class fakeOverLoad{
    //公開するメソッド
     function gattai($i_exp1 = null,$i_exp2 = null){
 
         //分岐ロジック
         switch (true) {
             //引数なしの場合
             case $i_exp1 === null && $i_exp2 === null:
                 return $this->gattai_null();
                 break;

             //文字列の場合
             case is_string($i_exp1) && is_string($i_exp1):
                 return $this->gattai_s($i_exp1,$i_exp2);
                 break;

             //整数型の場合
             case is_int($i_exp1) && is_int($i_exp1):
                 return $this->gattai_i($i_exp1,$i_exp2);
                 break;

             //オブジェクトの場合
             case is_object($i_exp1) && $i_exp2 === null:
                 //オブジェクトのクラス名で分岐
                 if(get_class($i_exp1) === "testString"){
                    return $this->gattai_obj($i_exp1);
                    break;
                 }

             //該当なし
             default:
                 return "引数指定できてない";
                 break;
         }
     }
          
     //以下隠ぺいするメソッド
     //引数なし
     private function gattai_null(){
         return "引数なし\n";
     }

     //文字列
     private function gattai_s($i_exp1,$i_exp2){
         return $i_exp1.$i_exp2." 文字列\n";
     }

     //整数     
     private function gattai_i($i_exp1,$i_exp2){
         return $i_exp1 + $i_exp2." 数値\n";
     }
    
     //オブジェクト     
     private function gattai_obj($i_exp1){
         return $i_exp1->getA().$i_exp1->getB()." オブジェクト(プロパティの文字列)\n";
     }
}

//引数用オブジェクト
class testString{
    private $a;
    private $b;
    
    public function setData($i_exp1,$i_exp2){
        $this->a = $i_exp1;
        $this->b = $i_exp2;        
    }
    
    public function getA(){
        return $this->a;
    }
    
    public function getB(){
        return $this->b;
    }
}

 //以下検証用コード
 $a = "1";
 $b = "2";

 $objOverLoad = new fakeOverLoad;
 
 //引数なし呼び出し
 echo $objOverLoad->gattai();

 //文字列型呼び出し
 echo $objOverLoad->gattai((String)$a,(String)$b);

 //整数型呼び出し
 echo $objOverLoad->gattai((integer)$a,(integer)$b);
 
 //オブジェクト型呼び出し
 $objTest = new testString;
 $objTest->setData($a,$b);
 
 echo $objOverLoad->gattai($objTest);

/* 出力結果 */
// 引数なし
// 12 文字列
// 3 数値
// 12 オブジェクト(プロパティの文字列)
?>

メリット

  • 呼び出す側からは個々のメソッドが隠蔽されていることでgattaiに処理を集約できるので、共通の処理等を実装しやすい。

デメリット

  • gattai内で分岐しなきゃならないから分岐ロジックが太るし書くのめんどい。
  • PHPDocなんかで引数コメントが書きづらく、参照しづらい。

まぁ。
PHPならPHPっぽく書けってことだよね、うん。