YD8877
YD8877

Reputation: 10790

PHP Classes : Call a specific function everytime a method call is made

I want to call a function every time a method call is made in PHP.

Example :

$a = new a();
$a->function1();

this would make 2 function calls: basicFunction() and then function1()

Same would be the case for any subsequent method calls of that class. is this possible in object oriented PHP?

Upvotes: 3

Views: 5551

Answers (5)

Gordon
Gordon

Reputation: 316969

The simplest would be to just call the method

public function function1 {
    $this->basicFunction();
    // …
}

What you are probably after is something like Aspect Oriented Programming. However, this is not common in PHP. The most notable use is in the Flow3 framework.

For other more common approaches usable with PHP OOP, have a look at

These would allow you to add arbitrary behavior and control flow at runtime.


(meta) On a sidenote, do we really need four answers suggesting to use __call? I suggest the various OPs review their respective answers, sort out the tiny differences and agree on which one is best. The other three could withdraw their answers then.

Upvotes: 6

Erik
Erik

Reputation: 20722

Sure, although it involves some overhead. The magic method _call will handle non-existing methods so you could do:

class myClass {
    public function __call($name, $arguments) {

        $this->doSomething();
        $this->$name($arguments);
    }

    private function calledmethod() { ... }

And then you'd call:

$class->calledmethod();

Since the method calledmethod isn't public, _call would get invoked then would run your 'base' method and then calledmethod.

I do feel obliged to ask, WHY do you need to do this? There's probably a more elegant solution if you'd describe the actual problem you're trying to solve.

Upvotes: 3

jwueller
jwueller

Reputation: 30996

There is nothing like this in PHP. You can, however, simulate this behaviour using the magic method __call():

class YourClass {
    public function __call($method, $args){
        // do what you want to do everywhere (i.e. call your basicFunction)
        return call_user_func_array(array($this, 'base'.ucfirst($method)), $args);
    }

    private baseSomeFunction() {
        // ...
    }
}

Usage:

$obj = new YourClass();
$obj->someFunction(); // this calls baseSomeFunction and executes the code
                      // in the __call() method

Prefixing your "magic" methods with something like base ensures that nobody can call your private functions and limits this access to only the functions that have been prefixed. You should change this prefix to suit your needs.

Upvotes: 3

cypher
cypher

Reputation: 6992

you have to use the __call magic method For your example:

class Foo{
    public function __call($method_name, $arguments){
        $this->basicFunction();
        return call_user_func_array(array($this, $method_name), $arguments);
    }


    private function basicFunction(){}
    protected function function1(){}
}

Upvotes: 0

StasM
StasM

Reputation: 11032

Use __call magic function like this:

class a {
  private function function1() { ... }
  public function __call($name, $args) {
       /* do stuff */;
       return call_user_func_array(array($this, $name), $args);
  }
}

Note however this won't work if function1() is called from inside the class. Then you'd have to rename function1() and call it with different name. The idea is that __call is invoked only if the function doesn't exist or can not be seen.

Upvotes: 0

Related Questions