2012-12-12 82 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

讓你鬆懈! –

相關問題