How to chain method on a newly created object?

Viewed 18033

I would like to know whether there's a way to chain methods on a newly created object in PHP?

Something like:

class Foo {
    public function xyz() { ... return $this; }
}

$my_foo = new Foo()->xyz();

Anyone know of a way to achieve this?

7 Answers

In PHP 5.4+, the parser's been modified so you can do something like this

(new Foo())->xyz();

Wrap the instantiation in parenthesis, and chain away.

Prior to PHP 5.4, when you're using the

new Classname();

syntax, you can't chain a method call off the instantiation. It's a limitation of PHP 5.3's syntax. Once an object is instantiated, you can chain away.

One method I've seen used to get around this is a static instantiation method of some kind.

class Foo
{
    public function xyz()
    {
        echo "Called","\n";
        return $this;
    }

    static public function instantiate()
    {
        return new self();
    }
}


$a = Foo::instantiate()->xyz();

By wrapping the call to new in a static method, you can instantiate a class with method call, and you're then free to chain off that.

It would be really helpful if they 'fix this' in a future release. I really appreciate the ability to chain (especially when populating collections):

I added a method to the base class of my framework called create() that can be chained off of. Should work with all descendant classes automatically.

class baseClass
{
    ...
    public final static function create()
    {
        $class = new \ReflectionClass(get_called_class());
        return $class->newInstance(func_get_args());
    }
    ...
    public function __call($method, $args)
    {
        $matches = array();
        if (preg_match('/^(?:Add|Set)(?<prop>.+)/', $method, $matches) > 0)
        {
            //  Magic chaining method
            if (property_exists($this, $matches['prop']) && count($args) > 0)
            {
                $this->$matches['prop'] = $args[0];
                return $this;
            }
        }
    }
    ...
}

Class::create()->SetName('Kris')->SetAge(36);

Related