【问题标题】:Cloning object with closures用闭包克隆对象
【发布时间】:2012-04-24 22:04:09
【问题描述】:

我在 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。我明白为什么会这样,因为我已经分配了一个局部变量,该变量嵌入到我的闭包定义中,随后嵌入到“钩子”属性中。

请提出解决此问题的方法。对于包含“可调用”属性的类,我如何克隆它并使闭包正确引用当前对象。也许我可以遵循不同的模式。谢谢!

【问题讨论】:

    标签: php object closures


    【解决方案1】:

    您可以在克隆时简单地覆盖$hook

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

    不确定您的示例是否代表您的实际代码。希望对你有帮助。

    在 PHP 5.4 中,可以直接在闭包中使用Closure::bindTo$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);
        }
    }
    

    【讨论】:

    • 太棒了。 bindTo 正是我所需要的,但你不认为你需要在重新绑定之前克隆你的闭包吗?这对我来说可能真的很管用。
    • 哦,实际上不需要克隆:来自文档:“创建并返回一个 new 匿名函数”。感谢您的精彩回答。
    【解决方案2】:

    我认为最简单的方法是self-encapsulation:

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

    【讨论】:

    • 但你会调用 $x->getA() 而不是 $y->getA()
    • 更新了一点,不确定是否有帮助,但可能:)
    猜你喜欢
    • 2019-03-21
    • 1970-01-01
    • 2011-11-07
    • 2013-11-14
    • 1970-01-01
    • 2013-01-03
    • 2017-02-11
    • 2011-07-10
    • 1970-01-01
    相关资源
    最近更新 更多