2012-12-12 83 views
7

我有一个PHP代码,看起来像这样:

class A { 
    public function __construct() { 
     $this->b = new B(function($x) { return $x + 1; }); 
    } 
}; 

class B { 
    public function __construct($dataProcessingFunction) { 
     $this->dataProcessingFunction = $dataProcessingFunction; 
    } 

    public function processData($data) { 
     $f = $this->dataProcessingFunction; 
     return $f($data); 
    } 
}; 

但有一个问题:我绝对需要B的析构函数之前的析构函数被调用。如你所见,这似乎是合理的。 B对象不需要任何A,所以应该没有问题。

但自PHP 5.4.0以来,闭包似乎会自动捕获$ this。因此,我传递给B并由B存储的lambda函数包含对A的引用。

这意味着A包含指向B的指针,并且B包含指向A的指针(通过闭包)。在这种情况下,PHP文档说析构函数只在垃圾回收时以随机顺序调用。并猜测:B的析构函数总是在A之前被调用。

有没有办法以优雅的方式解决这个问题?

+0

不“看起来” - 绝对如在anon func changelog中指出的那样:http://php.net/manual/en/functions.anonymous.php –

+0

我能想到的最优雅的方式是改变你的代码,让你不依赖于析构函数。依靠这样的特定命令可能会让你陷入困境。 – RonaldBarzell

+0

我没有PHP 5.4,所以我无法测试,但尝试使用'create_function'。你也许可以使用'Closure'类,或者只是改变函数绑定的内容(不是那么需要匿名的,我认为)。 –

回答

4

感谢爆炸药丸,我发现在Closure类的解决方案。

可以在事实上改变存储瓶盖内的$this,就像这样:

$cb = function($x) { return $x + 1; }; 
$cb = $cb->bindTo(null); 

// now $cb doesn't contain a pointer to $this anymore 

请注意,你不能这样做,否则你会得到一个语法错误:

// syntax error 
$cb = (function($x) { return $x + 1; })->bindTo(null); 
+0

D'oh ..这是我的代表! –

+0

让你松懈! –

相关问题