2010-07-13 5 views
21

J'essaie de comprendre comment attraper une méthode appelée sur un objet en PHP. Je connais la fonction magique __call, mais elle n'est déclenchée que pour les méthodes qui n'existent pas sur l'objet appelé.Comment intercepter un appel de méthode sur un objet en PHP?

Par exemple, j'ai quelque chose comme ceci:

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 
    } 
} 

Et quand je fais ceci:

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

Je veux que cette sortie:

Calling method bar 
foobar 

au lieu de celui-ci:

foobar 

Existe-t-il un moyen de le faire? Aide s'il vous plaît :)

Répondre

38

Prendre votre mise en œuvre Foo originale vous pouvez envelopper un decorator autour d'elle comme ceci:

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

Merci compagnon, c'est exactement ce dont j'avais besoin :) – Pirozek

+0

Un cas où cela ne fonctionnera pas est si vous avez des méthodes qui attendent 'Foo', par exemple' someMethod (Foo $ foo) ' –

2

Vous pouvez envelopper un objet autour de l'objet, intercepter tous les appels, puis les transférer sur l'objet d'origine et renvoyer le résultat. Il suffit de stocker l'objet en tant que variable dans votre classe wrapper et d'utiliser des méthodes de surcharge dans votre classe wrapper pour appeler/set/get/check sur l'objet.

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

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

La mise en boucle de la classe wrapper dans foreach est probablement plus difficile. Havent a essayé cela.

+0

Pouvez-vous être plus précis s'il vous plaît? Juste un petit exemple :) – Pirozek

+0

Merci mon pote, ça m'a aidé. – Pirozek

Questions connexes