Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to catch any method call on object in PHP?

I am trying to figure out how to catch any method called on an object in PHP. I know about the magic function __call, but it is triggered only for methods that do not exist on the called object.

For example i have something like this:

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

And when i do this:

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

I want this output:

Calling method bar foobar 

instead of this one:

foobar 

Is there any way how to do this? Help please :)

like image 745
Pirozek Avatar asked Jul 13 '10 22:07

Pirozek


2 Answers

Taking your original Foo implementation you could wrap a decorator around it like this:

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(); 
like image 88
ChristopheD Avatar answered Oct 05 '22 21:10

ChristopheD


You can wrap an object around the object, intercepting any calls then forwarding them on the original object and returning the result.

Just store the object as a variable in your wrapper class and use overloading methods in your wrapper class to call/set/get/check on the object.

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

Looping the wrapper class in foreach is probably harder. Havent tried that.

like image 24
OIS Avatar answered Oct 05 '22 21:10

OIS