views:

154

answers:

3

Hello, After seeing another question just started, I wanted to ask as to how something is actually achieved.

When I use some frameworks they do this like

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

How do you actually do this kinds of chains?

+1  A: 
class c
{
  function select(...)
  {
    ...
    return $this;
  }
  function from(...)
  {
    ...
    return $this;
  }
  ...
}

$object = new c;
just somebody
+7  A: 

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.

Pascal MARTIN
Thank you. And changing properties in the chain continues through. So I can set lets say a member $this->value in the method and it is changed as expected in the final method called. I have wondered how to do this, so thank you for the link.
Laykes
It seems like it is quite useful to ALWAYS use fluent interfacer for setters then? I $this->setValue(1) ; $this->setValueX(2); all the time. Using a fluent interface would make it a lot easier to read.
Laykes
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.
Pascal MARTIN
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".
Pascal MARTIN
+1  A: 

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.

Álvaro G. Vicario