【PHP】全く異なる複数クラスを疑似継承する黒魔術

  • 2019年9月19日
  • 2019年9月20日
  • PHP

 PHPの継承は常に単一です。これによって知るべき親クラスの情報を単純化してコードの複雑度を上げにくくしてあります。多段継承こそあれ複数経路は作れません。

class Hoge extends Foo // Foo一つを継承することはできる
class Fuga extends Foo,Bar // FooとBarを同時に継承するのはだめ

 やりかたはDI(Dependeny Injection)とマジックメソッドの応用です。

class Foo {
    public function echoFoo() {
        echo 'foo';
    }
    public function selfIntroduction() {
        echo "I'm foo.";
    }
}

class Bar {
    public function echoBar() {
        echo 'bar';
    }
    public function selfIntroduction() {
        echo "I'm bar.";
    }
}

class FooBar {
    public $foo;
    public $bar;
    
    public function __construct($foo, $bar)
    {
        // if コンストラクタでこけるのをいとわないか引数を気にしないなら:
        //     DIせず、ここで$this->foo = new Foo()の様に直接インスタンス化することもできる
        $this->foo = $foo;
        $this->bar = $bar;
    }

   public function __call($name, $arguments)
    {
        method_exists($this->foo, $name)
         ? $this->foo->$name($arguments)
         : $this->bar->$name($arguments);
    }
}

$f = new Foo();
$b = new Bar();
$fb = new FooBar($f, $b);
$fb->echoFoo();// foo
$fb->echoBar();// bar
$fb->selfIntroduction();// I'm foo.

 実行結果はコメントの通りになります。環境によってはセキュリティ問題でWARNINGが出ます。
 このようにするとFooBarインスタンスで未定義のメソッドが呼ばれたとき、DIしたfooのメソッドが存在するか確認し、fooにあればfooから実行、fooにもなければbarのメソッドを探し実行します。同様のやり方でstaticメソッド、プロパティも継承もどきができます。
 この方法を使えば簡単に全てのクラスの役割を持った神クラスを作れますが、もちろんそんな状態は作るべきでありません。複雑さに際限がなくなりコードを追うのも動作を理解するのも大変になります。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG