views:

100

answers:

5

Hi, In PHP, is there any way to make class method automatically call some other specified method before the current one? (I'm basically looking to simulate before_filter from Ruby on Rails.

For example, calling function b directly but getting the output 'hello you'.

function a() 
{
echo 'hello';
}

function b() 
{
echo 'you';
}

Any advice appreciated.

Thanks.

A: 

See http://stackoverflow.com/questions/1933050/check-if-function-has-been-called-yet/1933087#1933087

Also, why not have a look at the RoR sourcecode to see how it is implemented. Should be easy to port.

Gordon
A: 

PHP does not support filters.However, you could just modefy your own function to ensure that a() is always run before b().

function a() 
{ 
echo 'hello';
}

function b() 
{
a();
echo 'you';
}
Gerrit
A: 

Not if you're not willing to override a b() to call both.

You might be interested in AOP for PHP though.

Evert
I wouldn't recommend using something like AOP. This is a very basic premise of the language and trying to circumvent it will lead to cluttered and hard-to-understand code.
troelskn
I would agree, but it is a valid answer to the OP's problem though.
Evert
A: 

How about this:

function a() 
{
  echo 'hello';
}

function b() 
{
  a();
  echo 'you';
}

If you are under a class and both functions are in that class:

function a() 
{
  echo 'hello';
}

function b() 
{
  $this->a();
  echo 'you';
}

Not sure but possibly that's what you are looking for. thanks

Sarfraz
+1  A: 

Check this:

class Dispatcher {
    /*
     * somewhere in your framework you will determine the controller/action from path, right?
    */
    protected function getControllerAndActionFromPath($path) {
        /*
         * path parsing logic ...
        */
        if (class_exists($controllerClass)) {
            $controller = new $controllerClass(/*...*/);
            if (is_callable(array($controller, $actionMethod))) {
                $this->beforeFilter($controller);
                call_user_func(array($controller, $actionMethod));
                /*..
                 * $this->afterFilter($controller);
                 * ...*/
            }
        }
    }

    protected function beforeFilter($controller) {
        foreach ($controller->beforeFilter as $filter) {
            if (is_callable(array($controller, $filter))) {
                call_user_func(array($controller, $filter));
            }
        }
    }

    /*...*/
}

class FilterTestController extends Controller {
    protected $beforeFilter = array('a');

    function a() {
        echo 'hello';
    }

    function b() {
        echo 'you';
    }
}
knoopx
Minor thing: this will output 'hello hello' when calling `a()` in the controller
Gordon
right, same happens on rails with the difference you have :only and :except :)
knoopx