Basically the purpose of the static keyword is totally clear to me, the PHP docs only explain the purpose of the keyword in the context of classes. I noticed one of my IDE plugins suggesting me that I should declare many of my callback functions as static.
Without static:
$myUniqueArray = unique($arrayToFilter, function (ExamQuestion $examQuestion) { return $examQuestion->getId(); } );
With static:
$myUniqueArray = unique($arrayToFilter, static function (ExamQuestion $examQuestion) { return $examQuestion->getId(); } );
For the result it does not make a difference, it works both. What exactly is the difference between a callback function and a static callback function in PHP under the hood? What are possible benefits and drawbacks in this context?
Advertisement
Answer
You’re referring to Static Anonymous Functions [DOC] which are introduced as following in the documentation:
Anonymous functions may be declared statically. This prevents them from having the current class automatically bound to them. Objects may also not be bound to them at runtime.
If you compare that with the explanation of the static
keyword in the context of class methods [DOC], this might make the relation more clear. These are introduced as following in the documentation:
Because static methods are callable without an instance of the object created, the pseudo-variable
$this
is not available inside methods declared as static.
So an actual difference is that you don’t have $this
bound / available within the anonymous function when it is static
.
The reason why you get the suggestion within the IDE is that static anonymous functions give you a slightly better performance over the non-static variant. So unless you need $this
within the function, you can safely use the static
variant over the non-static one.
Anonymous functions have been introduced in PHP 5.3 [RFC] [5.3.0], with the addition of the static
keyword in PHP 5.4.
In PHP 5.3 $this
was not automatically bound when defined within a class (intentionally) which has been changed with PHP 5.4 and it is since then that $this
is automatically bound for the (non-static) anonymous function.
Since PHP 7.4 you can find arrow functions [DOC] which also come in the static/non-static flavours. However:
Arrow functions support the same features as anonymous functions, except that using variables from the parent scope is always automatic.
It’s not only $this
that a (non-static) arrow function would bound, it is (even for static ones) that all variables from the parent scope are automatically in use when in use. So this may hit performance more than given the occasional benefit of static
for anonymous functions.
NOTE: This is not only theoretical (you need to measure for performance comparisons) but it might also create the impression that all outer scope variables might be bound in the (static) arrow function. But, only those which have a literal variable expression (e.g.
$var
), not variable variables, not even superglobals butthis
(which errors in static context and therefore even if it might be bound there as well it would be useless), are available in the arrow function expression. You can safely usestatic
over not using it with arrow functions as well if you’re not making use of$this
in the arrow function expression (just to make it explicit again with this answer).
As you haven’t shared which IDE, it is only a guess to which concrete suggestion you’re referring to. Our educated guess is Phpstorm with the EA inspections plugin:
[EA] This closure can be declared as static (better scoping; in some cases can improve performance).
From the Static closures can be used EA inspection. And with the further information:
Analyzes closures and suggests using static closures instead.
This can bring additional performance improvements, e.g. as here:
Also, by using static function () {} closures, we squeezed out another 15% of hydration performance when dealing with private properties.
(from the inspection description provided by Php Inspections (EA Ultimate) within Phpstorm)