Ho un codice PHP che assomiglia a questo:
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);
}
};
Ma c'è un problema: ho assolutamente bisogno distruttore di B ad essere chiamato prima di distruttore di A. Questo sembra ragionevole, come puoi vedere. L'oggetto B non ha bisogno di A, quindi non ci dovrebbero essere problemi.
Ma dal momento che PHP 5.4.0, le chiusure sembrano automaticamente catturare implicitamente $ questo. Pertanto, la funzione lambda passata a B e memorizzata da B contiene un riferimento a A.
Ciò significa che A contiene un puntatore a B e B contiene un puntatore a A (attraverso la chiusura). In questo tipo di situazione, la documentazione di PHP dice che i distruttori vengono chiamati solo sulla garbage collection e in un ordine casuale. E indovina un po ': il distruttore di B viene sempre chiamato prima di A's.
C'è un modo per risolvere questo in modo elegante?
non "sembra" - sicuramente, come sottolineato nel anon func changelog: http://php.net/manual/en/functions.anonymous.php –
Il modo più elegante che posso pensare sarebbe quello di alterare il tuo codice in modo da non dipendono da un ordine di distruttore. Affidarsi a un ordine specifico come questo potrebbe metterti nei guai. – RonaldBarzell
Non ho PHP 5.4 dove sono così non posso testare, ma prova a usare 'create_function'. Potresti anche essere in grado di usare la classe 'Closure', o semplicemente cambiare a cosa è legata la funzione (non così anonima che richiederebbe un incarico, penso). –