Fluent interface for method chaining in PHP

Fluent interface for method chaining in PHP

I am currently doing some research to choose between one of the most popular PHP frameworks for my next project. I have experience using codeigniter and Yii, which are starting to be fairly low in the popularity scale nowadays. They are simple, straightforward and do the job, so I'm still happy to use them but I tend to try something new for every project I start in order to try and keep my skills up to date.

I've been playing around with Laravel and Symfony, which are the most popular frameworks right now. Laravel is quite new and wining in the popularity scale whereas Symfony has been properly stablished for some time now and is quite a robust and sophisticated framework. This, has made me discover a programming concept I didn't know that both of these frameworks use: fluent interface for method chaining. It's a very simple concept and it is almost surprising that it has a name, however I did find it weird at the begining since I wasn't familiar with the concept.

Fluent interface is an object-oriented construct that allows you to chain method calls that apply multiple operations on the same object, resulting in a more readable  code. It is thus syntactic sugar that eliminates the need to list the object repeatedly. For example, fluent interface allows us to write:

<?php

$client = new Client();
$client->setName('John')->setSurname('Smith')->setEmail('johnsmith@smythgn.com');

instead of

<?php

$client = new Client()
$client->setName('John')
$client->setSurname('Smith')
$client->setEmail('johnsmith@smythgn.com');

How to achieve this?

The answer is simple. On the Client class' setters, return a reference to the object being modified with $this:

<?php

class Client
{
    private string $name;
    private string $surname; 
    private string $email;

    public function setName(string $name)
    {
        $this->name = $name;

        return $this;
    }

    public function setSurname(string $surname)
    {
        $this->surname = $surname;

        return $this;
    }

    public function setEmail(string $email)
    {
        $this->email = $email;

        return $this;
    }

    public function __toString()
    {
        return "Name: {$this->name} {$this->surname }, email: {$this->email}";
    }
}

Now, we can call the methods as in the first example above:

<?php

$client = (new Client())
				->setName('John')
				->setSurname('Smith')
				->setEmail('johnsmith@smythgn.com');
print $client;
// Name: John Smith, email: johnsmith@smythgn.com

As a final comment, I think the main drawback (there's no free lunch) is that debugging errors can be a bit more difficult. It makes, however, the code more readable and there are less characters to be typed, then resulting in a quicker programming experience.

Show Comments