PHP method chaining?

Clash Royale CLAN TAG#URR8PPP
PHP method chaining?
I am using PHP 5 and I've heard of a new featured in the object-oriented approach, called 'method chaining'. What is it exactly? How do I implement it?
@Kristoffer the OP could easily have found how it is achieved from these questions.
– Gordon
Sep 16 '10 at 7:46
@Kristoffer in addition, searching for method chaining php on Google would have given the OP a tutorial by Salathe as the very first result. I dont mind answering easy questions, but some people are just too lazy.
– Gordon
Sep 16 '10 at 8:00
I submit for your perusal, the definitive method chaining decision tree
– rdlowrey
Aug 15 '12 at 6:30
8 Answers
8
Its rather simple really, you have a series of mutator methods that all returns the original (or other) objects, that way you can keep calling methods on the returned object.
<?php
class fakeString
private $str;
function __construct()
$this->str = "";
function addA()
$this->str .= "a";
return $this;
function addB()
$this->str .= "b";
return $this;
function getStr()
return $this->str;
$a = new fakeString();
echo $a->addA()->addB()->getStr();
This outputs "ab"
Try it online!
+1 mutator methods
– BoltClock♦
Sep 16 '10 at 6:18
This is also sometimes referred to as Fluent Interface
– Nithesh Chandra
Sep 16 '10 at 6:31
@Nitesh that is incorrect. Fluent Interfaces use Method Chaining as their primary mechanism, but it's not the same. Method chaining simply returns the host object, while a Fluent Interface is aimed at creating a DSL. Ex:
$foo->setBar(1)->setBaz(2) vs $table->select()->from('foo')->where('bar = 1')->order('ASC). The latter spans multiple objects.– Gordon
Sep 16 '10 at 7:32
$foo->setBar(1)->setBaz(2)
$table->select()->from('foo')->where('bar = 1')->order('ASC)
public function __toString() return $this->str; This will not require the last method "getStr()" if you're echoing out the chain already.
– tfont
Apr 22 '14 at 7:01
@tfont True, but then we're introducing magic methods. One concept at a time should be sufficient.
– Kristoffer Sall-Storgaard
Apr 22 '14 at 8:49
Basically, you take an object:
$obj = new ObjectWithChainableMethods();
Call a method that effectively does a return $this; at the end:
return $this;
$obj->doSomething();
Since it returns the same object, or rather, a reference to the same object, you can continue calling methods of the same class off the return value, like so:
$obj->doSomething()->doSomethingElse();
That's it, really. Two important things:
As you note, it's PHP 5 only. It won't work properly in PHP 4 because it returns objects by value and that means you're calling methods on different copies of an object, which would break your code.
Again, you need to return the object in your chainable methods:
public function doSomething()
// Do stuff
return $this;
public function doSomethingElse()
// Do more stuff
return $this;
Could you do
return &$this in PHP4?– alex
Sep 16 '10 at 6:18
return &$this
@alex: I don't have PHP 4 to test with right now, but I'm pretty sure not.
– BoltClock♦
Sep 16 '10 at 6:23
I didn't think so either, but it should work right? Perhaps if PHP4 wasn't so PHP4-ish.
– alex
Sep 16 '10 at 6:26
You can get the complete simple steps of the method chaining at techflirt.com/tutorials/oop-in-php/php-method-chaining.html
– Ankur Kumar Singh
Feb 19 at 11:41
Try this code:
<?php
class DBManager
private $selectables = array();
private $table;
private $whereClause;
private $limit;
public function select()
$this->selectables = func_get_args();
return $this;
public function from($table)
$this->table = $table;
return $this;
public function where($where)
$this->whereClause = $where;
return $this;
public function limit($limit)
$this->limit = $limit;
return $this;
public function result()
$query = "SELECT";
// if the selectables array is empty, select all
if (empty($this->selectables))
$query = "*";
// else select according to selectables
else
$query = join(', ', $this->selectables);
$query = "FROM";
$query = $this->table;
if (!empty($this->whereClause))
$query = "WHERE";
$query = $this->whereClause;
if (!empty($this->limit))
$query = "LIMIT";
$query = $this->limit;
return join(' ', $query);
// Now to use the class and see how METHOD CHAINING works
// let us instantiate the class DBManager
$testOne = new DBManager();
$testOne->select()->from('users');
echo $testOne->result();
// OR
echo $testOne->select()->from('users')->result();
// both displays: 'SELECT * FROM users'
$testTwo = new DBManager();
$testTwo->select()->from('posts')->where('id > 200')->limit(10);
echo $testTwo->result();
// this displays: 'SELECT * FROM posts WHERE id > 200 LIMIT 10'
$testThree = new DBManager();
$testThree->select(
'firstname',
'email',
'country',
'city'
)->from('users')->where('id = 2399');
echo $testThree->result();
// this will display:
// 'SELECT firstname, email, country, city FROM users WHERE id = 2399'
?>
this is what i call a good explanation...chaining methods always gives me goosebumbs!!
– MYNE
Feb 12 '16 at 13:24
How I identify (inside the method) the first and last elements (calls) in the chain. Because sometimes this is now just a list of operations to be executed in order, but something that should be done after collecting all elements. Like executing an SQL query here - but beware, you could do multiple chained calls on one object! Firt and last in each.
– Andris
Apr 4 at 22:45
Method chaining means that you can chain method calls:
$object->method1()->method2()->method3()
This means that method1() needs to return an object, and method2() is given the result of method1(). Method2() then passes the return value to method3().
Good article: http://www.talkphp.com/advanced-php-programming/1163-php5-method-chaining.html
The explanation is a bit off. The return values are not passed around. The methods simply return the host object.
– Gordon
Sep 16 '10 at 8:19
@Gordon Well, the host object is not returned. Any object can be returned and chained.
– alexn
Sep 16 '10 at 14:38
Then I would argue it's not method chaining as defined by Fowler, e.g. Make modifier methods return the host object so that multiple modifiers can be invoked in a single expression. - if you return other objects, it's more likely a Fluent Interface :)
– Gordon
Sep 16 '10 at 14:58
@Gordin Point taken :)
– alexn
Sep 16 '10 at 17:03
Wow, I realize that I'm commenting on an almost 8 year old post.. But your link that you have there, is redirecting to some other website. Just fyi.
– willbeeler
Oct 19 '17 at 18:41
There are 49 lines of code which allows you to chain methods over arrays like this:
$fruits = new Arr(array("lemon", "orange", "banana", "apple"));
$fruits->change_key_case(CASE_UPPER)->filter()->walk(function($value,$key)
echo $key.': '.$value."rn";
);
See this article which shows you how to chain all the PHP's seventy array_ functions.
http://domexception.blogspot.fi/2013/08/php-magic-methods-and-arrayobject.html
This isn't really an answer so much as a link to a webpage with a potential answer.
– faintsignal
Dec 14 '16 at 22:16
Another Way for static method chaining :
class Maker
private static $result = null;
private static $delimiter = '.';
private static $data = ;
public static function words($words)
if( !empty($words) && count($words) )
foreach ($words as $w)
self::$data = $w;
return new static;
public static function concate($delimiter)
self::$delimiter = $delimiter;
foreach (self::$data as $d)
self::$result .= $d.$delimiter;
return new static;
public static function get()
return rtrim(self::$result, self::$delimiter);
echo Maker::words(['foo', 'bob', 'bar'])->concate('-')->get();
echo "<br />";
echo Maker::words(['foo', 'bob', 'bar'])->concate('>')->get();
class JobModel implements JobInterface
protected $job;
public function __construct(Model $job)
$this->job = $job;
public function find($id)
return $this->job->find($id);
public function with($data=)
$this->job = $this->job->with($params);
return $this;
class JobController
protected $job;
public function __construct(JobModel $job)
$this->job = $job;
public function index()
// chaining must be in order
$this->job->with(['data'])->find(1);
can you explain what does this do?
– ichimaru
Jun 19 at 5:40
If you mean method chaining like in JavaScript (or some people keep in mind jQuery), why not just take a library that brings that dev. experience in PHP? For example Extras - https://dsheiko.github.io/extras/ This one extends PHP types with JavaScript and Underscore methods and provides chaining:
You can chain a particular type:
<?php
use DsheikoExtrasArrays;
// Chain of calls
$res = Arrays::chain([1, 2, 3])
->map(function($num) return $num + 1; )
->filter(function($num) return $num > 1; )
->reduce(function($carry, $num) return $carry + $num; , 0)
->value();
or
<?php
use DsheikoExtrasStrings;
$res = Strings::from( " 12345 " )
->replace("/1/", "5")
->replace("/2/", "5")
->trim()
->substr(1, 3)
->get();
echo $res; // "534"
Alternatively you can go polymorphic:
<?php
use DsheikoExtrasAny;
$res = Any::chain(new ArrayObject([1,2,3]))
->toArray() // value is [1,2,3]
->map(function($num) return [ "num" => $num ]; )
// value is [[ "num" => 1, ..]]
->reduce(function($carry, $arr)
$carry .= $arr["num"];
return $carry;
, "") // value is "123"
->replace("/2/", "") // value is "13"
->then(function($value)
if (empty($value))
throw new Exception("Empty value");
return $value;
)
->value();
echo $res; // "13"
This doesn't really answer the question ("What is method chaining?"). Also the original question is 8 years old and has already got a number of better answers
– GordonM
Apr 12 at 9:39
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
I'd say most if not all of those questions are about technicalities regarding chaining, this is more specifically about how to achieve it.
– Kristoffer Sall-Storgaard
Sep 16 '10 at 7:39