catch method calles and parameters passed to an object

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
jmut
Forum Regular
Posts: 945
Joined: Tue Jul 05, 2005 3:54 am
Location: Sofia, Bulgaria
Contact:

catch method calles and parameters passed to an object

Post by jmut »

I decided to share this little snippet with you guys. I came up with it a few days ago.
Basically, the idea is to be able to catch the event before calling a method and after calling it transparantly for the caller!!

USAGE/PROS:
- logging what parameters you give and which method you call.
- trace/follow through wich method calls a script goes during execution.
- don't change any original class. Use as is. Only change is when creating the object. Rest usage is the same.

CONS:
- should slow the applicaation...no idea how much


This is only made to work for PHP 5.* as it uses the Reflection API. (would like not to use it if possible but haven't thought how yet :))

Here is some example:

Code: Select all

//pass first argument...the name of the class you want to build....next are the values you usually pass as arguments to the constructor.
//usually will use some factory class to do it.
$obj = factorNewClass::buildObject('Useful_Class','value1','value2');

/* @var $obj Useful_Class */
$obj->fixAll();


class Useful_Class {

    private $param1 = '';
    private $param2 = '';

    public function __construct($param1,$param2) {
        $this->param1 = $param1;
        $this->param2 = $param2;
    }


    public function fixAll() {
        echo "Fixing all bugs ...yeah you wish. Param 1 is : {$this->param1}...Param2 is: {$this->param2}";
    }

}


class factorNewClass {

    private $obj = null;
    private $dbgStr = '';

    public function __construct()  {}

    static public function buildObject() {
        $args = func_get_args();
        $className = array_shift($args);
        $rfl = new ReflectionClass($className);
        $var = new self();
        $var->obj = call_user_func_array(array($rfl,'newInstance'),$args);
        return $var;
    }

    function __call ($name,$args) {
        $class_name = get_class($this->obj);
        echo "calling {$class_name}::{$name}() \n";
        $this->dbgStr = print_r($args,1);
        return call_user_func_array(array($this->obj,$name),$args);
    }
}

The best part of this is that....whenever you want to disablle this you just change the factory class to build objects from the original Class.
For this to work to be best of course...you should not build any aditional method to factorNewClass() ...because once you return to using the original
class you will end up with method not defined.
So basically for extra functionality you should use external class (for example for debugging you don't add debug() method to factorNewClass() but use other class all together).

Let me know what you think :)
Maybe there are better ways to do it.
jmut
Forum Regular
Posts: 945
Joined: Tue Jul 05, 2005 3:54 am
Location: Sofia, Bulgaria
Contact:

Post by jmut »

Now the problem I so with this one is interface stuff.
If you try to put your object in some specific object type context it will probably fail.
As your object is of type "factorNewClass" and not "Useful_Class".
Maybe it could be refactored to magically achive this as well.
Post Reply