This is an interesting quirk I found while method chaining and I’m having difficulty bypassing it. I’m sure there’s a solution or another way. It’s tough to explain but I’ll do my best.
Example:
You have three functions which are part of a class, as well as 2 protected properties as follows.
class Chain {
protected $_str = '';
protected $_part = 0;
public function __toString() {
return implode(' ', $this->_str);
}
public function AAA () {
$this->_str[$this->_part] = 'AAA';
$this->_part++;
return $this;
}
public function BBB () {
$this->_str[$this->_part] = 'BBB';
$this->_part++;
return $this;
}
public function wrap ($str) {
$part = $this->_part - 1;
$this->_str[$part] = "({$str})";
return $this;
}
}
Now when chaining these methods and specifically using the wrap method, the strings from previous chains are unintentionally appended. Example:
$chain = new Chain();
$chain->AAA()->BBB()->wrap($chain->AAA());
echo $chain;
What you would expect the string to look like is AAA BBB (AAA).
However, what actually returns is AAA BBB (AAA BBB AAA).
Why is it that wrap() takes all the previous methods called within the chain instead of only the method that’s actually wrapped by it? What is the best way around this assuming there is one?
$chain->AAA()->BBB()is doing the first two ‘AAA’ and ‘BBB’ – obvious.Then the
$chain->AAA()which comes insidewrap($chain->AAA())does the 3rd ‘AAA’.and last, the
wrapmethod takes all the three and wraps them with()and concatenated to the first ‘AAA’ and ‘BBB’ using this line:$this->_str[$part] = "({$str})";which resolves to:
AAA BBB (AAA BBB AAA).UPDATE:
I believe that what you’re trying to do, is to avoid the side-effect of returning
thisfrom methodsAAA()andBBB()– will be achieved with the following changes: