这是一个有趣的怪癖,我发现方法链接时,我很难绕过它。我确信有解决方案或其他方式。这很难解释,但我会尽我所能。
示例:
您有三个函数属于类的一部分,以及2个受保护的属性,如下所示。
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()
采用链中调用的所有先前方法而不仅仅是实际包含它的方法?假设有一个最好的方法是什么?
答案 0 :(得分:2)
$chain->AAA()->BBB()
正在做前两个'AAA'和'BBB' - 显而易见
然后$chain->AAA()
内的wrap($chain->AAA())
执行第3个'AAA'
最后,wrap
方法获取所有三个并用()
包装它们并使用以下行连接到第一个'AAA'和'BBB':$this->_str[$part] = "({$str})";
哪个结算致:AAA BBB (AAA BBB AAA).
<强>更新强>
我相信您要做的是避免从方法this
和AAA()
返回BBB()
的副作用 - 将通过以下更改实现:
<?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();
?>
答案 1 :(得分:1)
我称之为'竞争条件'。似乎PHP首先解释$chain->AAA()->BBB()
。
然后$chain->_part
为2,$chain->_str
为'AAA BBB'。
然后,为了能够调用wrap,参数,所以运行$chain->AAA()
。
然后$chain->_part
为3,$chain->_str
为'AAA BBB AAA'。
最后调用wrap,扭曲'AAA BBB AAA'。我会分开wrap() - 调用并将$chain->_part
重置为零。
答案 2 :(得分:0)
调用队列是:
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()
内置链(在第3步之后是AAA BBB AAA)字符串in(),所以你在_part
数组末尾有AAA BBB AAA字符串。