Stack Overflow Asked by learning php on December 30, 2021
The example in the php documentation on Closure::bind
include static
on the anonymous function declaration. why? I can’t find the difference if it is removed.
with:
class A {
private static $sfoo = 1;
}
$cl1 = static function() { // notice the "static"
return self::$sfoo;
};
$bcl1 = Closure::bind($cl1, null, 'A');
echo $bcl1(); // output: 1
without:
class A {
private static $sfoo = 1;
}
$cl1 = function() {
return self::$sfoo;
};
$bcl1 = Closure::bind($cl1, null, 'A');
echo $bcl1(); // output: 1
I beg to differ. It's true that often it won't matter. But sometimes it matters a whole lot.
The closure holding a reference to $this
might prevent garbage collection of that object, which in turn may also impact performance significantly. Here's an example where it really makes a huge difference:
class LargeObject {
protected $array;
public function __construct() {
$this->array = array_fill(0, 2000, 17);
}
public function getItemProcessor(): Closure {
// Try with and without 'static' here
return static function () {
// do some processing unrelated to $this
};
}
}
$start = microtime(true);
$processors = [];
for ($i = 0; $i < 2000; $i++) {
$lo = new LargeObject();
$processors[] = $lo->getItemProcessor();
}
$memory = memory_get_usage() >> 20;
$time = (microtime(true) - $start) * 1000;
printf("This took %dms and %dMB of memoryn", $time, $memory);
Here's the output with a normal closure:
This took 55ms and 134MB of memory
Here's the output with a static closure:
This took 22ms and 1MB of memory
I tested this with PHP 7.3.19 on Debian Buster, so YMMV. Obviously this is a specially constructed example to demonstrate the difference. But things like this may happen in real applications as well. I started using Slevomat's SlevomatCodingStandard.Functions.StaticClosure sniff to remind me to always use static closures.
Answered by jlh on December 30, 2021
Static Closures, like any other static method, cannot access $this
.
Like any other method, a non-static Closure that does not access $this
will generally work in a static context.
Answered by Hendrik Rombach on December 30, 2021
found the difference: you can't bind static closures to object, only change the object scope.
class foo { }
$cl = static function() { };
Closure::bind($cl, new foo); // PHP Warning: Cannot bind an instance to a static closure
Closure::bind($cl, null, 'foo') // you can change the closure scope
Answered by learning php on December 30, 2021
As you've noticed, it doesn't really matter.
It's like using the static
keyword on a class method. You don't necessarily need it if you don't reference $this
within the method (though this does violate strict standards).
I suppose PHP can work out you mean the Closure
to access A
statically due to the null
2nd argument to bind()
Answered by Phil on December 30, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP