2012-02-05 8 views
2

親メソッドを非表示にして、親クラスで定義されたメソッドに対して子クラスの__callマジックメソッドが呼び出されるようにしたいとします。例:PHP:親メソッドを__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とリフレクションから隠蔽します。私はプロキシの実装をきれいにして、基本クラスから継承してプロキシインタフェースを実装するだけで済むようにしようとしていました。基本クラスのインターフェイスを維持するために、プロキシ開発者は、リモート呼び出しを行うためにすべてのpublicおよびprotectedメソッドを再実装する必要があります。次に、基本クラスで何かが更新されると、プロキシも同様に更新する必要があります。結局のところ、私は単に、リフレクションを使用するプロキシジェネレータを作成するルートを開発者に委ねるつもりだと思います。

返信いただきありがとうございます!私はこの質問は少し古いですけど、私はそれが同じに直面して人々を助けるために、私はそれをここに投稿しそう働いてしまった

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}'"); 
     } 
    } 
} 

答えて

2

問題。魔法の__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()メソッドを持つことができないということです)メソッドを拡張子クラスではなく親クラスから削除します。

+0

この場合、基本クラスはプロキシなしでは使用できません。 –

+0

これは可能ですが、親クラスに魔法の '__call'メソッドを追加し、そこから呼び出されたメソッドを呼び出さなければなりません。私の編集した答え –

+4

でtrigger_errorを見る2012年に...例外を使用してください。)私は、さらに 'call_user_func_array'に' __CLASS__'または 'self'を使用して、 – meze

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(); 
+0

静的 –

+0

保護法が継承され、正常に呼び出されることに殴られたように見える –

+0

は、はい、それは静的メソッドを呼び出します。このメソッドを呼び出します - それが要件となり静的メソッドを持つけれども私はもともといただきたいが、それはないと変更$ this'が結果に影響しません 'に' __CLASS__'です。正当な理由がない限り、私は一般に「プライベート」よりも「保護された」方が好きです。私はここで区別がパブリックメソッドが 'private'または' protected'のいずれかが動作するはず理由は優先して呼び出されることだと思います。 –

0

を:あなたはprivatefooメソッドへのアクセス権を設定する必要が

関連する問題