2012-02-07 14 views
1

私はメソッドを委譲したいと思っているいくつかのPHPクラフトを持っています。一種の貧しい人のミックスイン。PHPはメソッドを呼び出すために__getを使用しますか?

基本的に私は、次のようになる:

<?php 

class Apprentice 
{ 
    public function magic() { 
     echo 'Abracadabra!'; 
    } 
} 

class Sourcerer // I work magic with the source 
{ 
    private $apprentice; 

    public function __construct(){ 
     $this->apprentice = new Apprentice(); 
    } 

    public function __get($key) { 
     if (method_exists($this->apprentice, $key)) { 
      return $this->apprentice->{$key}; 
     } 
     throw Exception("no magic left"); 
    } 
} 

$source = new Sourcerer(); 
$source->magic(); 
?> 

Fatal error: Call to undefined method Sourcerer::magic() in .../test__get.phpをスローしないように。

答えて

9
public function __call($name, $args) { 
    if (method_exists($this->apprentice, $name)) { 
     return $this->apprentice->$name($args); 
    } 
    throw Exception("no magic left"); 
} 

PS:__getような方法のための使用__callは、プロパティだけのためのものです。 はい、call_user_func_arrayを使用する方が良いです。それ以外の場合は、引数は配列としてmagic関数に渡されます。

return call_user_func_array(array($this->apprentice, $name), $args); 
+0

これは++です。 __callはあなたが本当に探しているものです。さらに、今後このような機能を静的関数で使用する場合は、__callStaticを調べることをお勧めします。 – Navarr

+0

Ohhh ...私はドキュメント全体を誤って読んでいました。 '__call()'は、それが関数であるかのようにインスタンスを呼び出すためのもので、 '$ s = new S(); $ s(); 'ありがとう! – quodlibetor

+0

@quodlibetorメソッド['__invoke'](http://php.net/manual/en/language.oop5.magic.php#object.invoke)はインスタンスを関数のように呼び出すためのものです。 – Wilt

1

あなたの呼び出しは、代わりに次のようになります。

​​

はまた、私は__get()魔法のメソッドはプロパティではなく、メソッド名に働くと考えています。

最後に、実際の__get()定義では、構文が間違っています:throw new Exception('message');である必要があります。私はelse句に移動します。それ以外の場合は、if/elseまたは他のロジックの外にあるので、関係なく、それぞれのコールをトリガーします。

return $this->apprentice->$key(); 
  • あなたは__getメソッドを呼び出しません$source->magic()を、使用している:実際にあなたが実際にそのようにそれを呼び出す必要があります、apprentice上のメソッドを呼び出すことが

  • +0

    次の構文についての権利、および 'else'(' if'はリターンを持っているの必要について間違っています。 )しかし、検索の連鎖は私が避けようとしているものです。 – quodlibetor

    3
    1. __get$source->magicのような可変アクセスですが、$source->magic()は関数呼び出しです。関数呼び出しのためのマジックメソッドを望むなら、それは__callです。

    2

    よりのような__callの代わりに、あなたのケースで__get

    class Sourcerer // I work magic with the source 
    { 
        private $apprentice; 
    
        public function __construct(){ 
         $this->apprentice = new Apprentice(); 
        } 
    
        public function __call($name, $arguments) { 
         if (method_exists($this->apprentice, $name)) { 
          return call_user_func_array(array($this->apprentice, $name), $arguments); 
         } 
         throw Exception("no magic left"); 
        } 
    } 
    
    関連する問題