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

Bla*_*bam 9 php static callback anonymous-function

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

无静态:

$myUniqueArray = unique($arrayToFilter,
    function (ExamQuestion $examQuestion) {
        return $examQuestion->getId();
    }
);
Run Code Online (Sandbox Code Playgroud)

与静态:

$myUniqueArray = unique($arrayToFilter,
    static function (ExamQuestion $examQuestion) {
        return $examQuestion->getId();
    }
);
Run Code Online (Sandbox Code Playgroud)

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

hak*_*kre 12

您指的是静态匿名函数[DOC],文档中介绍如下:

\n
\n

匿名函数可以静态声明。这可以防止当前类自动绑定到它们。对象在运行时也可能不绑定到它们。

\n
\n

如果将其与类方法[ DOC ]static上下文中关键字的解释进行比较,这可能会使关系更加清晰。这些在文档中介绍如下:

\n
\n

由于静态方法无需创建对象实例即可调用,因此伪变量$this在声明为静态的方法内不可用。

\n
\n

$this因此,实际的区别在于,当匿名函数为 时,您在匿名函数中没有绑定/可用static

\n

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

\n
\n

PHP 5.3 [RFC] [5.3.0]中引入了匿名函数,并在 PHP 5.4 中添加了关键字。 static

\n

在 PHP 5.3 中,$this当在类中定义时(有意)不会自动绑定,而 PHP 5.4 对此进行了更改,从那时起,它就$this自动绑定为(非静态)匿名函数。

\n

从 PHP 7.4 开始,您可以找到也有静态/非静态风格的箭头函数[DOC] 。 然而:

\n
\n

箭头函数支持与匿名函数相同的功能,只是使用父作用域中的变量始终是自动的。

\n
\n

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

\n
\n

注意:这不仅是理论上的(您需要测量性能比较),而且还可能给人一种印象,即所有外部作用域变量都可能绑定在(静态)箭头函数中。但是,只有那些具有文字变量表达式(例如 $var)的变量,而不是变量变量,甚至不是超全局this变量(在静态上下文中会出错,因此即使它也可能绑定在那里,它也是无用的),在箭头中可用函数表达式。static如果您没有在箭头函数$this表达式中使用(只是为了通过此答案再次明确它),您也可以安全地使用而不是不将其与箭头函数一起使用。

\n
\n
\n

由于您没有共享哪个 IDE,因此只能猜测您所指的是哪个具体建议。我们有根据的猜测是带有EA 检查插件的Phpstorm :

\n
\n

[EA] 这个闭包可以声明为静态(更好的范围;在某些情况下可以提高性能)。

\n
\n

静态闭合可以用EA检查。并提供更多信息:

\n
\n

分析闭包并建议使用静态闭包。

\n

这可以带来额外的性能改进,例如

\n
\n

此外,通过使用 static function () {} 闭包,我们在处理私有属性时又挤出了 15% 的水合性能。

\n
\n
\n

(来自 Phpstorm 内的 Php Inspections \xe2\x80\x8b(EA Ultimate)\xe2\x80\x8b 提供的检查描述)

\n