tags:

views:

55

answers:

3

I have a class:

class Module {

    public function a(...params...) {
        //do something, doesn't return anything
    }

    public function b(...params...) {
        //do something, doesn't return anything
    }

    public function c(...params...) {
        //do something, doesn't return anything
    }

    public function getAsArray() {
        return get_object_vars($this);
    }

}

Is it possible to modify module class, so methods a(),b() and c() return $this? I don't want to write it in every function. getAsArray() should return what it does. Module will be base for other classes and I want this mechanism to be implemented in base, but use it in inheriting classes.

I want to use it like this:

$module = new Module();
$module->a()->b()->c()->getAsArray();
A: 

There are some situations where i use this baseclass:

abstract class FluentInterface
{
    public function __call($method, $params)
    {
        if(substr($method, 0, 3) == 'set')
        {
            // remove leading 'set' from method
            $prop = substr($method, 3);
            // lowercase first char
            $prop{0} = strtolower($prop{0});

            $rc = new ReflectionClass(get_class($this));
            if($rc->hasProperty($prop))
            {
                $this->$prop = $params[0];
                return $this;
            }
        }

        return false;
    }
}

But it is specifically designed for getters/setters. Maybe you could expand a little on your specific problem domain.

Dennis Haarbrink
+1  A: 

If you don't want to add a single line returning $this to each of your methods, you can do something like:

class Module {

    private function _a($value) {
        echo 'Executing method a<br />';
        $this->aVar = $value;
    }

    private function _b($value) {
        echo 'Executing method b<br />';
        $this->bVar = $value;
    }

    private function _c($value) {
        echo 'Executing method c<br />';
        $this->cVar = $value;
    }

    public function getAsArray() {
        return get_object_vars($this);
    }

    public function __call($name, $arguments) {
        echo 'Calling method '.$name.'<br />';
        call_user_func_array(array($this,'_'.$name),$arguments);
        return $this;
    }
}


$x = new Module();

var_dump($x->a(1)->b(2)->c(3)->getAsArray());

though it's really more work for you to do than the single line change that you seem to dislike.

Note that you can't incorporate immediate method calls into a new Module line in any way. This does actually require you to store the instantiated object in a variable, and then chain the method calls against that variable.

Mark Baker
That is what I thought about, but this requires adding prefix to every method definition. It is better than adding `return $this` to every method, but still painful. It is not one line, every method in inheriting classes has to return `$this` and I don't want to write it there.
LukLed
Is there any particular reason why you don't want to write a return $this into each method?
Mark Baker
It is unnecessary code redundancy. Why should I write it if I don't need to?
LukLed
It isn't code redundancy though. Default behaviour for any method in PHP is to return a NULL: choosing to return any other value (including $this) is necessary, additional code.
Mark Baker
It is necessary, additional code, which I wan't to have in one, single place, not in every function. I wan't to have it for a branch of classes.
LukLed
+1  A: 

No.

Either you do it by hand or write a program to go through the source files and do it for you.

Manos Dilaverakis