How to programatically change every method to return $this (except predefined list)?

StackOverflow https://stackoverflow.com/questions/3265181

  •  16-09-2020
  •  | 
  •  

Question

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();
Was it helpful?

Solution

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.

OTHER TIPS

No.

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

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top