I have a PHP code that looks like this:
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);
}
};
But there is a problem: I absolutely need B's destructor to be called before A's destructor. This seems reasonable as you can see. The B object doesn't need any A, so there should be no problem.
But since PHP 5.4.0, closures seem to automatically capture implicitly $this. Therefore, the lambda function that I pass to B and that is stored by B contains a reference to A.
Which means that A contains a pointer to B, and B contains a pointer to A (through the closure). In this kind of situation, the PHP documentation says that destructors are only called on garbage collection and in a random order. And guess what: B's destructor is always called before A's.
Is there a way to solve this in a elegant way?
Which statement is not allowed in anonymous function? As of PHP 7.1, these variables must not include superglobals, $this , or variables with the same name as a parameter. A return type declaration of the function has to be placed after the use clause.
Anonymous functions, also known as closures , allow the creation of functions which have no specified name. They are most useful as the value of callable parameters, but they have many other uses. Anonymous functions are implemented using the Closure class.
Yes, use a closure: functionName($someArgument, function() use(&$variable) { $variable = "something"; }); Note that in order for you to be able to modify $variable and retrieve the modified value outside of the scope of the anonymous function, it must be referenced in the closure using & . It's new!
The advantage of an anonymous function is that it does not have to be stored in a separate file. This can greatly simplify programs, as often calculations are very simple and the use of anonymous functions reduces the number of code files necessary for a program.
Thanks to Explosion Pills, I've found the solution in the Closure
class.
You can in fact change the $this
stored inside the closure, like this:
$cb = function($x) { return $x + 1; };
$cb = $cb->bindTo(null);
// now $cb doesn't contain a pointer to $this anymore
Note that you can't do this, or you'll get a syntax error:
// syntax error
$cb = (function($x) { return $x + 1; })->bindTo(null);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With