12

Commonly, in a lot of frameworks, you can find examples of creating a query using the query builder. Often you will see:

$query->select('field');
$query->from('entity');

However, in some frameworks you can also do it like this

$object->select('field')
       ->from('table')   
       ->where( new Object_Evaluate('x') )
       ->limit(1) 
       ->order('x', 'ASC');

How do you actually do this kinds of chains?

3 Answers 3

18

This is called Fluent Interface -- there is an example in PHP on that page.

The basic idea is that each method (that you want to be able to chain) of the class has to return $this -- which makes possible to call other methods of that same class on the returned $this.

And, of course, each method has access to the properties of the current instance of the class -- which means each method can "add some information" to the current instance.

Sign up to request clarification or add additional context in comments.

4 Comments

You're welcome :-) ;; yes, each method can set/change properties, and the "last" method is often used to "execute" whatever the previous methods were called to configure.
Not sure using fluent interface will always make code easier to read ;;; when it's used to build some SQL query, for instance, it makes sense ; but when the methods are not really related, not so sure -- depends on the situation, I suppose ;;; a great thing being that even if your methods return $this, they can be called "in a typical way".
Does it have to return $this? Can't it return $that and continue from there?
@PascalMARTIN So there isn't a way to trigger the host method (with all the method set values) without casting a string using Fluent Interfaces?
7

Basically, you have to make every method in the class return the instance:

<?php

class Object_Evaluate{
    private $x;
    public function __construct($x){
        $this->x = $x;
    }
    public function __toString(){
        return 'condition is ' . $this->x;
    }
}
class Foo{
    public function select($what){
        echo "I'm selecting $what\n";
        return $this;
    }
    public function from($where){
        echo "From $where\n";
        return $this;
    }
    public function where($condition){
        echo "Where $condition\n";
        return $this;
    }
    public function limit($condition){
        echo "Limited by $condition\n";
        return $this;
    }
    public function order($order){
        echo "Order by $order\n";
        return $this;
    }
}

$object = new Foo;

$object->select('something')
       ->from('table')
       ->where( new Object_Evaluate('x') )
       ->limit(1)
       ->order('x');

?>

This is often used as pure eye candy but I suppose it has its valid usages as well.

3 Comments

Use case: $setup = $Object->add_component($component_property)->configure($component_properties); Where Object::add_component() returns the Component object it added as a property of $Object (eg. to an array), and it is configured with the Component::configure() method. Without chaining, we would have to determine that last element added to the $Object->Components array, then get the Component object that way.
@AVProgrammer - Your example does not make use of return $this, does it?
Yes it does, the Component object does this, to allow for the configure() method.
2
class c
{
  function select(...)
  {
    ...
    return $this;
  }
  function from(...)
  {
    ...
    return $this;
  }
  ...
}

$object = new c;

Comments

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.