2

親で定義されたメソッドに対して子クラスの__callマジックメソッドが呼び出されるように、何らかの方法で親メソッドを非表示にしたいと思います。例えば:

class C {
  function foo() { echo "foo\n"; }
}

class D extends C {
  function __call( $method, $args ) { echo "called $name\n"; }
}

$d = new D();
$d->foo();

// desired result: called foo
// actual result: foo

rename_functionとoverride_functionにチェックインしましたが、これらはメソッドでは機能しません。ReflectionMethodには私が試したsetAccessibleメソッドがありますが、これはReflectionMethodインスタンスを使用してメソッドを呼び出す場合にのみ機能するようです。

背景:PHPの型チェックを利用できるRPCプロキシクラスを作成しようとしています。したがって、RPCFooがある場合は、型ヒントまたはinstanceofを使用して、それを確認できるように型を強制できます($ RPCFooインスタンスFoo)。

編集:基本クラスは、プロキシなしでそのまま使用できる必要があります。これは、プロキシがコードではなくシステム構成の一部になるようにするためです。すべて同じコードベースを持つ複数のサーバーを考えてみてください。ただし、それぞれに特定のタスクを割り当てることができます。ローカルサーバーが要求されたサービスを処理しない場合、クラスローダーは基本クラスの代わりにプロキシを返します。ローカルサーバーが要求されたサービスを処理する場合、ローカルサーバーは基本クラスを返します。

もう一度編集:提示されたメソッドは実行可能ですが、基本クラスの設計されたインターフェイスをIDEとリフレクションから隠します。基本クラスから継承してプロキシインターフェイスを実装するだけで済むように、プロキシ実装をクリーンにしようとしていました。基本クラスのインターフェースを維持するために、プロキシ開発者は、リモート呼び出しを行うためにすべてのパブリックメソッドと保護されたメソッドを再実装する必要があります。次に、基本クラスで何かが更新されると、プロキシも更新する必要があります。結局、私は単に、リフレクションを使用するプロキシジェネレーターを作成するルートをたどり、開発者のためにこれを行うつもりだと思います。

返信ありがとうございます!

4

3 に答える 3

2

fooメソッドへのアクセスを次のように設定する必要がありますprivate

class C {
    private function foo() {
        echo "foo\n";
    }
    public function __call($method, $args) {
        if(is_callable(array($this,$method))) {
            return call_user_func_array(array($this,$method), $args);
        } else {
            trigger_error("Call to undefined method '{$method}'");
        }
    }
}
于 2012-02-05T18:22:57.070 に答える
0
class C {

    public function __call($method, $args) {
        return call_user_func_array(array(__CLASS__ ,$method), $args);
    }

    protected function foo() { echo "foo<br />"; }
}

class D extends C {
    function __call( $method, $args ) { echo "called $method<br/>"; }
}

$d = new D();
$d->foo();

$c = new C();
$c->foo();
于 2012-02-05T19:48:17.793 に答える
0

この質問は少し古いことは知っていますが、うまくいったので、同じ問題に直面している人々を助けるためにここに投稿します。

魔法の __call() メソッドで親メソッドをオーバーライドする私の解決策:

public function foo($p1, $p2, $p3)
{
    if (get_class($this) == __CLASS__) {
        /* Do stuff here */
    } elseif (method_exists($this, '__call')) {
        return call_user_func_array([$this, '__call'], ['foo', func_get_args()]);
    }

    return false;
}

唯一の制限は、親クラス自体がマジック __call() メソッドを持つことができないことです。そうしないと、拡張された子クラスの代わりに親クラスから __call() メソッドが呼び出されます。

于 2014-10-07T15:44:20.040 に答える