1

PHP5.3には次のクラスがあります。

class MyClass {
    public $a=1;
    public $hook;
    function setHook(){
        $t=$this;
        $this->hook=function() use($t){
            echo $t->a;
        };
   }
}

次の構文は期待どおりに機能します。

$x = new MyClass();
$x->setHook();
call_user_func($x->hook);     // outputs 1;

ただし、このコードを続行すると、次のようになります。

$y = clone $x;
$y->a = 2;
call_user_func($y->hook);

その後も1が出力されます。クロージャの定義に埋め込まれ、続いて「フック」プロパティに埋め込まれたローカル変数を割り当てたため、なぜ発生するのか理解できます。

この問題を回避する方法を提案してください。「呼び出し可能」なプロパティを含むクラスの場合、それをクローン化し、クロージャが現在のオブジェクトを適切に参照するようにするにはどうすればよいですか。おそらく私は別のパターンに従うことができます。ありがとう!

4

2 に答える 2

2

$hookクローンを作成するときに、単純に上書きできます。

public function __clone() {
    $this->setHook();
}

あなたの例があなたの実際のコードを代表しているかどうかわからない。お役に立てば幸いです。

Closure::bindToPHP 5.4では、クロージャーで$this直接使用できます。

class MyClass {
    public $a = 1;
    public $hook;

    public function setHook(){
        $this->hook=function() {
            echo $this->a;
        };
    }

    public function __clone() {
        $this->hook = $this->hook->bindTo($this);
    }
}
于 2012-04-12T16:19:08.267 に答える
0

最も簡単な方法は自己カプセル化だと思います:

private function getA() { return $this->a;}

$this->hook=function(){
        echo $this->getA();
}
于 2012-04-12T14:27:04.930 に答える