【问题标题】:Does a PHP static anonymous function really work?PHP 静态匿名函数真的有效吗?
【发布时间】:2014-05-09 07:57:11
【问题描述】:

我正在尝试学习 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'

为什么这行代码不起作用“return static function(){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();

【问题讨论】:

  • static 关键字在returnfunction() 之间是问题所在,你试图达到什么目的?
  • 不,不是。问题是没有使用 PHP 5.4+

标签: php anonymous-function


【解决方案1】:

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

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

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

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

所以:

$bar = $f->bar();

$bar();

结果:

注意:未定义变量:this in /in/Bpd3d on line 5

$baz = $f->baz();

$baz();

结果

对象(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 中的静态闭包

注意:未定义变量:this in /in/h63iF on line 9

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

【讨论】:

  • 请注意,从 PHP 7.1 开始,上述答案中的所有通知和警告都被视为Fatal errors
【解决方案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..."

【讨论】:

  • 也许你的意思是static而不是strict
  • 他问的是语法错误,而不是他是否应该使用静态匿名函数。静态匿名与匿名不同。
猜你喜欢
  • 2021-12-12
  • 1970-01-01
  • 1970-01-01
  • 2017-05-27
  • 2010-10-13
  • 1970-01-01
  • 2010-10-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多