Posted by: SEO Positive

Posted on: November 3, 2010 9:12 am

-

Method chaining is becoming an increasingly popular technique in the programmers world, but not a lot of people understand it.

This short tutorial will hopefully shed light on:

  1. what it is
  2. what it does

So what is method chaining?

To answer this question I have to show you some basic classes, see below for a standard class and method set.

class random_functions{
     function format($string, $f = 'uppercase'){
            switch($f){
                 case 'uppercase':
                       $string = strtoupper($string);
                 break;
                 case 'lowercase':
                       $string = strtolower($string);
                 break;
             }
             return $string;
     }
     function strings($string, $filter = 'trim'){
            switch($filter){
                  case 'trim':
                         $string = trim($string);
                  break;
                  case 'mres':
                         $string = mysql_real_escape_string($string);
                  break;
             }
             return $string;
      }
}

To use the above class, instantiation is the usual

$functions = new random_functions();
echo $functions->strings($functions->format($string, 'lowercase'), 'mres');

Which, to me at least, looks awful, its hard to read and just generally not very easy to work with.
What method chaining allows us to do is keep our functions separate and make our re-usable code a lot easier to read and understand as this requires a lot of logical thought in to how you want it to work and even makes planning easier due to having to put your functions in the correct order to achieve what you want.

See below for the same class that allows method chaining.

class random_functions{

     static $output = '';

     function format($string, $f = 'uppercase'){
            switch($f){
                 case 'uppercase':
                       self::$output = strtoupper($string);
                 break;
                 case 'lowercase':
                       self::$output = strtolower($string);
                 break;
             }
             return $this;
     }
     function strings($string = '', $filter = 'trim'){
            switch($filter){
                  case 'trim':
                         self::$output = $string ? trim($string) : trim(self::$output);
                  break;
                  case 'mres':
                         self::$output = $string ? mysql_real_escape_string($string) : mysql_real_escape_string(self::$output);
                  break;
             }
             return $this;
      }
      function output($in = ''){
             echo $in ? $in : self::$output;
             return $this;
      }
}

And the use of this is much clearer and much easier, see below for the use and an explanation of the code.

$functions = new random_functions();
$functions->format('Foo Bar', 'lowercase')->strings()->output();

As you can see, there are arrows between each function call, this is called method chaining. This helps us keep our code clean, semantic and easy to read and understand.

Lets analyze the code

In order to make things easier I added a class variable to work from, this variable is available to every function within the class and I use it to validate input to functions and give us something to work from and around if needed. I also changed each return.

Instead of returning our formatted string, I’ve changed each return to $this what $this means is “the current object” which in a class means the class object.

The class object?

Classes are objects, with children (the methods/functions within the class) and to make any function chainable within a class all you have to do is return an object. You cannot make static methods chainable i.e

class random_functions{

     static $output = '';

     static function format($string, $f = 'uppercase'){
            switch($f){
                 case 'uppercase':
                       self::$output = strtoupper($string);
                 break;
                 case 'lowercase':
                       self::$output = strtolower($string);
                 break;
             }
             return $this;
     }
    static function strings($string = '', $filter = 'trim'){
            switch($filter){
                  case 'trim':
                         self::$output = $string ? trim($string) : trim(self::$output);
                  break;
                  case 'mres':
                         self::$output = $string ? mysql_real_escape_string($string) : mysql_real_escape_string(self::$output);
                  break;
             }
             return $this;
      }
     static function output($in = ''){
             echo $in ? $in : self::$output;
             return $this;
      }
}

random_functions::format('Foo Bar', 'lowercase')::strings()::output();

Will not work, this will return a fatal error.

But to make a static method chainable you must return a new object as $this is undefined in a static method as the parent becomes self

We hope that you enjoyed this tutorial and its helped you understand the ideology of method chaining and how it is useful.

Authors
Categories
Archives
Blogroll