这是我在方法链接时发现的一个有趣的怪癖,我很难绕过它。我相信有解决方案或其他方法。这很难解释,但我会尽力的。
示例:
您有三个函数,它们是一个类的一部分,还有两个受保护的属性,如下所示。
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;
}
}
现在,当链接这些方法时,特别是使用wrap方法时,会无意中附加以前链中的字符串。示例:
$chain = new Chain();
$chain->AAA()->BBB()->wrap($chain->AAA());
echo $chain;
您所期望的字符串是AAA BBB (AAA)
。
然而,实际返回的是AAA BBB (AAA BBB AAA)
。
为什么wrap()
接受链中以前调用的所有方法,而不是只接受它实际包装的方法?假设有一个,最好的方法是什么?
$chain->AAA()->BBB()
正在执行前两个"AAA"answers"BBB"-显而易见
然后进入wrap($chain->AAA())
内部的$chain->AAA()
进行第三次"AAA"
最后,wrap
方法获取所有三个,并用()
包裹它们,并使用以下行连接到第一个"AAA"answers"BBB":$this->_str[$part] = "({$str})";
,解析为:AAA BBB (AAA BBB AAA).
更新:
我相信,您所要做的是避免从方法AAA()
和BBB()
返回this
的副作用-将通过以下更改实现:
<?php
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 "AAA";
}
public function BBB () {
$this->_str[$this->_part] = 'BBB';
$this->_part++;
return "BBB";
}
public function wrap ($str) {
$part = $this->_part - 1;
$this->_str[$part] = "({$str})";
return $str;
}
}
$chain = new Chain();
$chain->AAA();
$chain->BBB();
$chain->wrap($chain->AAA());
echo $chain->__toString();
?>
我称之为一种"竞赛条件"。PHP似乎首先解释了$chain->AAA()->BBB()
。
则$chain->_part
为2,$chain->_str
为"AAA BBB"。
然后,为了能够调用wrap,参数,所以运行$chain->AAA()
。
则CCD_ 18为3,CCD_。
最后,包裹被称为"AAA BBB AAA"。我会分离wrap()-调用,并在两者之间将$chain->_part
重置回零。
调用队列为:
1. $chain->AAA() //this is first method not in wrap() method, you have now AAA
2. $chain->BBB() //then next method, you have now AAA BBB
3. $chain->AAA() //again AAA() method inside wrap method, so you have AAA BBB AAA
在wrap()
中,您将链(第三步后为AAA BBB AAA)字符串放入()中,因此在_part
数组的末尾有AAA BBB AA字符串。