2010-07-13 11 views
21

Sto cercando di capire come catturare qualsiasi metodo chiamato su un oggetto in PHP. Conosco la funzione magica __call, ma è attivata solo per metodi che non esistono sull'oggetto chiamato.Come catturare qualsiasi chiamata di metodo su un oggetto in PHP?

Per esempio io ho qualcosa di simile:

class Foo 
{ 
    public function bar() 
    { 
    echo 'foobar'; 
    } 

    public function override($method_name,$method_args) 
    { 
    echo 'Calling method ',$method_name,'<br />'; 
    $this->$method_name($method_args); //dirty, but working 
    } 
} 

E quando faccio questo:

$foo = new Foo(); 
$foo->bar(); 

Voglio che questa uscita:

Calling method bar 
foobar 

invece di questo:

foobar 

Esiste un modo per farlo? Aiuto per favore :)

risposta

38

Prendendo il vostro Foo implementazione originale si potrebbe avvolgere un decorator intorno in questo modo:

class Foo 
{ 
    public function bar() { 
     echo 'foobar'; 
    } 
} 

class Decorator 
{ 
    protected $foo; 

    public function __construct(Foo $foo) { 
     $this->foo = $foo; 
    } 

    public function __call($method_name, $args) { 
     echo 'Calling method ',$method_name,'<br />'; 
     return call_user_func_array(array($this->foo, $method_name), $args); 
    } 
} 

$foo = new Decorator(new Foo()); 
$foo->bar(); 
+0

Grazie amico, questo è esattamente quello di cui avevo bisogno :) – Pirozek

+0

Un caso in cui questo non funzionerebbe è se hai metodi che si aspettano 'Foo', ad esempio' someMethod (Foo $ foo) ' –

2

È possibile avvolgere un oggetto intorno all'oggetto, intercettare eventuali chiamate, quindi inoltrarle sull'oggetto originale e restituire il risultato.

Basta archiviare l'oggetto come variabile nella classe wrapper e utilizzare i metodi di overloading nella classe wrapper per chiamare/impostare/ottenere/controllare l'oggetto.

$object = new AnyObject; 
$object = new Wrapper($object); 

$object->anyMethod(); 
$object->anyVar = 'test'; 
echo $object->anyVar; 
echo $object['array form']; 

Inclinare la classe wrapper in foreach è probabilmente più difficile. Havent ci ha provato.

+0

Può essere più specifico per favore? Solo un piccolo esempio :) – Pirozek

+0

Grazie amico, questo mi ha aiutato. – Pirozek

Problemi correlati