Mam kod PHP, który wygląda tak:
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);
}
};
Ale jest problem: ja absolutnie potrzebne destruktor B nazywać przed za destructor. Wydaje się to rozsądne, jak widać. Obiekt B nie potrzebuje żadnego A, więc nie powinno być problemu.
Jednak od czasu wydania 5.4.0 .pc, zamknięcia wydają się automatycznie przechwytywać niejawnie $ this. Dlatego funkcja lambda przekazywana do B i przechowywana przez B zawiera odniesienie do A.
Co oznacza, że A zawiera wskaźnik do B, a B zawiera wskaźnik do A (przez zamknięcie). W tej sytuacji dokumentacja PHP mówi, że destruktory są wywoływane tylko podczas zbierania śmieci i w losowej kolejności. I zgadnij co: destruktor B jest zawsze wywoływany przed A.
Czy istnieje sposób na rozwiązanie tego problemu w elegancki sposób?
nie "wydawać" - definitywnie, jak wskazano w dzienniku funkcji anon func: http://php.net/manual/en/functions.anonymous.php –
Najbardziej eleganckim sposobem, jaki mogę wymyślić, jest zmiana kodu, dzięki czemu nie są zależne od kolejności destruktora. Poleganie na określonej kolejności, takiej jak ta, może wpędzić cię w kłopoty. – RonaldBarzell
Nie mam PHP 5.4 gdzie jestem, więc nie mogę przetestować, ale spróbuj użyć 'create_function'. Możesz również skorzystać z klasy 'Closure' lub po prostu zmienić to, do czego funkcja jest przypisana (nie tak anonimowa, jak wymagałoby to przypisania). –