0

I have seen people do this:

$controller->bar->stuff->foo();

I suppose this is CLASS chaining?

How is this achievable? (if at all achievable)

NOTE. I am not asking about method chaining.

Cheers!

EDIT: Forgot to ask this... how would this benefit me? If you guys could write a short example it'd be great!

1
  • 3
    There is no such thing as "class chaining". $controller has a property bar; whatever is in it has a property stuff; whatever is in there has a method foo; and this method will be invoked. Commented Jun 11, 2014 at 0:51

1 Answer 1

4

This is achieved via accessible properties. For example, using public properties...

class Stuff {
    public function foo() {}
}

class Bar {
    /**
     * @var Stuff
     */
    public $stuff;

    public function ___construct(Stuff $stuff) {
        $this->stuff = $stuff;
    }
}

class Controller {
    /**
     * @var Bar
     */
    public $bar;

    public function __construct(Bar $bar) {
        $this->bar = $bar;
    }
}

$stuff = new Stuff();
$bar = new Bar($stuff);
$controller = new Controller($bar);

$controller->bar->stuff->foo();

I wouldn't recommend this as it leaves your classes open to external modification. Another method might be via magic getter methods, for example

class Controller {
    private $properties = [];

    public function __construct(Bar $bar) {
        $this->properties['bar'] = $bar;
    }

    public function __get($name) {
        return array_key_exists($name, $this->properties)
            ? $this->properties[$name] : null;
    }
}

This means you can still access the property in the private $properties array like it was a public property (eg $controller->bar) without it being open to external modification.

In my opinion though, keep properties private / protected and provide accessor methods

class Controller {
    /**
     * @var Bar
     */
    private $bar;

    public function __construct(Bar $bar) {
        $this->bar = $bar;
    }

    /**
     * @return Bar
     */
    public function getBar() { return $this->bar; }
}

$controller->getBar()->someBarMethod()->etc();
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the answer. I've got one more question. Not sure if you have ever used CodeIgniter, but... CI has something similar - $this->input->post()... is this achieved the same way?
I've never used CI. I suggest you dig into the source code if you want to find out. From what I've seen, I certainly wouldn't hold it up as a beacon of good OOP.
+1 for the great explanation. Just a side question, would the second block of code be better suited as a registry object? :)
@Darren That pattern could be used as a registry but I was really only trying to show how the magic __get method works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.