【问题标题】:What exactly is the difference between an anonymous function and a static anonymous function in PHP?PHP中的匿名函数和静态匿名函数到底有什么区别?
【发布时间】:2021-12-12 22:57:37
【问题描述】:

基本上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中的回调函数和静态回调函数到底有什么区别?在这种情况下可能有哪些好处和坏处?

【问题讨论】:

  • 我认为this thread 中的答案涵盖了其中的几个部分,包括在某些(可能是边缘情况)场景下的潜在性能提升

标签: php callback static anonymous-function


【解决方案1】:

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

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

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

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

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

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


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

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

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

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


由于您尚未共享哪个 IDE,因此您所指的具体建议只是猜测。我们有根据的猜测是带有EA inspections plugin 的 Phpstorm:

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

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

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

这可以带来额外的性能改进,例如作为here:

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

(来自 Phpstorm 内的 Php Inspections ​(EA Ultimate)​提供的检查说明)

【讨论】:

  • 关于 IDE,你是完全正确的。不过不认识这个详细信息,谢谢!
  • 您可以展开工具提示,它通常会显示更多信息,如果需要更多空间进行解释,它会链接到 EA 检查 Github。
  • 关于箭头函数,如果有任何潜在的性能cost 没有明确的 use 子句:当前的实现对于它捕获的变量相当“贪婪”。例如,以下表达式捕获了$bigArray 的副本,尽管它不需要,因为 preg_match 会覆盖它而不读取它:$bigArray=range(1,1_000_000); $string='hello;' $callback = fn() => preg_match('/(l*)/', $string, $bigArray);
  • @IMSoP:好点,在写完句子之后读一下。我应该采用那里的措辞。对于当前的 PHP,可能没有对箭头函数进行优化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-29
相关资源
最近更新 更多