1

これは、メソッドの連鎖中に見つけた興味深い癖であり、バイパスするのに苦労しています。解決策または別の方法があると確信しています。説明するのは難しいですが、最善を尽くします。

例:

クラスの一部である 3 つの関数と、次の 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()実際にチェーンによってラップされたメソッドだけではなく、チェーン内で呼び出された以前のすべてのメソッドを取得するのはなぜですか? あると仮定すると、これを回避する最良の方法は何ですか?

4

3 に答える 3

2

$chain->AAA()->BBB()最初の 2 つの 'AAA' と 'BBB' を実行しています - 明らかです。
すると$chain->AAA()中に入っwrap($chain->AAA())た が 3 番目の「AAA」をします。
最後に、このwrapメソッドは 3 つすべてを取得し、次の行を使用してそれらをラップし()、最初の「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();

?>
于 2012-07-15T03:41:20.470 に答える
1

私はそれを一種の「競合状態」と呼んでいます。PHPが最初にを解釈するよう$chain->AAA()->BBB()です。

次に$chain->_part2で、$chain->_str「AAABBB」です。

次に、引数であるwrapを呼び出せるようにするために、so$chain->AAA()が実行されます。

次に$chain->_part3で、$chain->_str「AAABBBAAA」です。

最後にラップが呼び出され、「AAABBBAAA」がワープアップされます。wrap()呼び出しを分離し$chain->_part、その間にゼロにリセットします。

于 2012-07-15T03:43:09.397 に答える
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)文字列を()に入れているので、配列の最後にAAABBBAAA文字列があり ます_part

于 2012-07-15T03:50:17.923 に答える