phpでオブジェクトの継承元のメソッドを別のクラスから呼び出す方法post

phpで実装上どうしてもタイトルのような事をしないといけなかったのでその方法のメモ。 そもそもの話、実装がまずいって事のような気がすご???くするんだけど、それは置いておこう。

前提

順に挙げると、

  1. クラスA と クラスB と クラスC があります。
  2. クラスB は クラスA を継承しています。
  3. クラスC は クラスA および クラスB とは関連がありません。
  4. この時、クラスC から クラスB のオブジェクトインスタンスを使い、クラスA のメソッドを呼び出すにはどうしたらよいだろうか?
  5. ただし、呼び出すメソッドは クラスB ですでにオーバーライドされていることする。

とりあえず、前提はこんな感じ。

ソースを載せると↓な感じ。

<?php
class C {
    private $a;
    function __construct($owner) { $this->a = $owner; }
    public function test($v) {
        // ここで $this->a を使い A::test を呼び出したい!
    }
}
class A {
    public function test($v) { return '!' . $v; }
}
class B extends A {
    private $c;
    function __construct()   { $this->c = new C($this); }
    public function test($v) { return $this->c->test($v); }
}
$b = new B;
echo $b->test('test') . "\n";

つまり、 クラスB::test() → クラスC::test() → クラスA::test() って感じで呼び出したい。

試行

色々ググってみる。

リフレクション使ったりとか、 (array)$hoge したりで private な、メンバ変数が取得出来たりとかアレなことをしていたりしてみた。

けど、ふと public なメソッドなら call_user_func() で呼び出せるんだから、クラス名付ければ呼び出せないか?と気が付いた。

やってみたら、すんなり行ってしまった。

解決

該当部分だけ抜き出すと、

public function test($v) { // C::test()
    return call_user_func(array($this->a, 'A::test'), $v);
}

って感じ。

クラス名は、 get_parent_class() で取得してもいいかもしれない。

完全なソースは あるオブジェクトの親クラス(派生元クラス)のメソッドを外部から呼び出す - GitHub Gist に置きました。

実は、PHP: call_user_func - Manualこのあたりにもさりげなく匂わせる感じでは書いてあったりしたけど、、、見落としていた。


   /   変更履歴  /   Permalink  /  このエントリーをはてなブックマークに追加 
 カテゴリ: ブログ  /   タグ: php, Develop