2010-07-13 13 views
21

Estoy intentando descubrir cómo atrapar cualquier método llamado a un objeto en PHP. Conozco la función mágica __call, pero se activa solo para los métodos que no existen en el objeto llamado.Cómo atrapar cualquier llamada de método en objeto en PHP?

Por ejemplo tengo algo como esto:

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

Y cuando hago esto:

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

Quiero esta salida:

Calling method bar 
foobar 

en lugar de éste:

foobar 

¿Hay alguna manera de cómo hacer esto? Ayuda por favor :)

Respuesta

38

Tomando su implementación original Foo que podría envolver un decorator alrededor de él así:

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

Gracias amigo, eso es exactamente lo que necesitaba :) – Pirozek

+0

Un caso en el que esto no funcionará es si tiene métodos que esperan 'Foo', por ejemplo' someMethod (Foo $ foo) ' –

2

Puede envolver un objeto alrededor del objeto, interceptando cualquier llamada y luego reenviando el objeto original y devolviendo el resultado.

Simplemente almacene el objeto como una variable en su clase contenedora y use métodos de sobrecarga en su clase contenedora para llamar/establecer/obtener/verificar el objeto.

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

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

Looping la clase contenedora en foreach es probablemente más difícil. Havent lo intentó.

+0

¿Puede ser más específico, por favor? Solo un pequeño ejemplo :) – Pirozek

+0

Gracias amigo, esto me ayudó. – Pirozek

Cuestiones relacionadas