PHP中的匿名函数和静态匿名函数到底有什么区别?

What exactly is the difference between an anonymous function and a static anonymous function in PHP?

基本上 the static keyword 的目的对我来说是完全清楚的,PHP 文档只解释了关键字在 类 上下文中的目的。我注意到我的一个 IDE 插件建议我应该将我的许多回调函数声明为静态的。

没有静态:

$myUniqueArray = unique($arrayToFilter,
    function (ExamQuestion $examQuestion) {
        return $examQuestion->getId();
    }
);

静态:

$myUniqueArray = unique($arrayToFilter,
    static function (ExamQuestion $examQuestion) {
        return $examQuestion->getId();
    }
);

对于结果来说,这没有什么区别,两者都有效。 PHP 中的回调函数和静态回调函数到底有什么区别?在这种情况下可能有哪些好处和缺点?

您指的是Static Anonymous Functions [DOC],文档中介绍如下:

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.

如果您将其与 class methods [DOC][=59 上下文中 static 关键字的解释进行比较=],这可能会使关系更清楚。这些在文档中介绍如下:

Because static methods are callable without an instance of the object created, the pseudo-variable $this is not available inside methods declared as static.

所以一个实际的区别是当匿名函数是 static 时你没有 $this 绑定/可用。

您在 IDE 中得到建议的原因是静态匿名函数为您提供了比非静态变体稍微好一些的性能。因此,除非您在函数中需要 $this,否则您可以安全地使用 static 变体而不是非静态变体。


匿名函数已在 PHP 5.3 中引入,有无 static 关键字 [RFC] [5.3.0]。在 PHP 5.3 中,$this 在 class 中定义时不会自动绑定(有意),并且在 PHP 5.4 中已更改,从那时起 $this 是自动绑定到(非静态)匿名函数。

从 PHP 7.4 开始,您可以找到 arrow functions [DOC],它也有 static/non-static 风格。然而:

Arrow functions support the same features as anonymous functions, except that using variables from the parent scope is always automatic.

不仅$this(非静态)箭头函数会绑定,而且(即使对于静态函数)父作用域中的所有变量都会自动使用。因此,这更有可能影响性能,而不是偶尔为匿名函数带来 static 的好处。


由于您还没有分享哪个 IDE,因此只能猜测您指的是哪个具体建议。我们有根据的猜测是 Php风暴与 EA inspections plugin:

[EA] This closure can be declared as static (better scoping; in some cases can improve performance).

可以使用静态闭包 EA 检查。以及更多信息:

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.

(来自PhpInspections (EA Ultimate) 在Phpstorm中提供的检查说明)

hakre 接受的回答非常有用,但我认为有一点是错误的。

静态箭头函数和静态匿名函数的性能是一样的:

这个:

$x = 123;
static function () { return true; }

与此一样高效:

$x = 123;
static fn() => true;

接受的答案假定箭头函数较慢,因为 $x 总是在箭头函数中捕获 by-value。这是不正确的,因为如果不使用 $x(如我的示例),则不会捕获 by-value。我通过简单地使用 PHP 的 get_defined_vars().

对其进行了测试