PHP静态匿名函数真的有效吗?

2022-08-31 00:20:50

我正在尝试学习PHP,现在我陷入了“静态匿名函数”的困境。

我在教程中发现了这一点(http://www.slideshare.net/melechi/php-53-part-2-lambda-functions-closures-presentation)

“面向对象

  • Lambda 函数之所以是闭包,是因为它们会自动绑定到在其中创建它们的类的作用域。
  • '$this' 在作用域中并不总是必需的。
  • 删除“”可以节省内存。$this
  • 您可以通过将 Lambda 函数声明为静态来阻止此行为。

此代码有什么问题?

我收到此错误:

解析错误:解析错误,期望在第 11 行的 C:\wamp\www\z-final\a.php中出现“T_PAAMAYIM_NEKUDOTAYIM”

为什么这个代码行不起作用“返回静态函数(){var_dump($this);};”?

class foo
{
    public function getLambda()
    {
        return function(){var_dump($this);};
    }

    public function getStaticLambda()
    {
        return static function(){var_dump($this);};
    }
}

$foo = new foo();
$lambda = $foo->getLambda();
$staticLambda = $foo->getStaticLambda();
$lambda();
$staticLambda();

答案 1

是的,这是5.4+中完全有效的语法。

基本上,它阻止了当前类自动绑定到闭包(实际上,它阻止了所有绑定,但稍后会详细介绍)。

class Foo {
    public function bar() {
        return static function() { var_dump($this); };
    }
    public function baz() {
        return function() { var_dump($this); };
    }
}

如果我们在 5.4+ 上实例化它,则返回的闭包将设置为 null。就像你对它进行了静态调用一样。但会设置为您调用的 foo 实例。bar()$thisbaz()$thisbaz()

所以:

$bar = $f->bar();

$bar();

结果在:

注意:未定义的变量:此在第 5 行的 /in/Bpd3d 中

$baz = $f->baz();

$baz();

结果在

object(Foo)#1 (0) {

}

有意义?伟大。

现在,如果我们采用在函数外部定义的闭包会发生什么:

$a = function() { var_dump($this); };
$a();

我们收到(和通知)null

$c = $a->bindTo(new StdClass());
$c();

我们得到,正如你所期望的那样StdClass

$b = static function() { var_dump($this); };
$b();

我们收到(和通知)null

$d = $b->bindTo(new StdClass());
$d();

这就是事情变得有趣的地方。现在,我们得到一个警告,一个通知,并返回 null:

警告:无法将实例绑定到第 12 行 /in/h63iF 中的静态闭包

注意:未定义的变量:这在第 9 行的 /in/h63iF 中

因此,在 5.4+ 中,你可以声明一个静态闭包,这导致它永远不会绑定到它,你也不能将对象绑定到它...$this


答案 2

应该没有必要用关键字来定义它。static

<?php
class House
{
     public function paint($color)
     {
         return function() use ($color) { return "Painting the house $color..."; };
     }
}

$house = new House();
$callback = $house->paint('red');
var_dump($callback); // object(Closure)#2 (2) {..}
var_dump($callback()); // "Painting the house red..."

推荐