为什么我不能在PHP 5.5.4中使用$ this作为词法变量?

tjb*_*jbp 40 php

$ php --version
PHP 5.5.4 (cli) (built: Sep 19 2013 17:10:06) 
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2013 Zend Technologies
Run Code Online (Sandbox Code Playgroud)

以下代码(类似于https://bugs.php.net/bug.php?id=49543上的示例):

class Foo
{
    public function bar()
    {
        return function() use ($this)
        {
            echo "in closure\n";
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

失败了:

PHP Fatal error:  Cannot use $this as lexical variable
Run Code Online (Sandbox Code Playgroud)

然而根据PHP文档和对Rasmus Lerdorf的错误报告的评论,从PHP 5.4开始,在匿名函数中使用$ this.我究竟做错了什么?

tjb*_*jbp 56

因此,如果未通过"use"关键字指定,则可以简单地使用$ this.

以下回声'酒吧':

class Foo
{
    private $foo = 'bar';

    public function bar()
    {
        return function()
        {
            echo $this->foo;
        };
    }
}

$bar = (new Foo)->bar();

$bar();
Run Code Online (Sandbox Code Playgroud)

这是在php-internals邮件列表中报告的,显然由于5.3缺乏对此功能的支持而过剩:

http://marc.info/?l=php-internals&m=132592886711725

  • 对于PHP 7用户来说,这个答案仍然是绝对正确的. (11认同)

Spu*_*ley 8

我不知道答案,你的实际问题(即为什么你不能做到这一点),但我可以绕给你一个工作:使用的临时副本$this,并use()认为不是:

class Foo
{
    public function bar()
    {
        $that = $this;
        return function() use($that)
        {
            print_r($that);
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

我刚试过它,这确实有效.


coo*_*ner 8

PHP 5.3如果您使用的是封闭类的内部时,Closure将无法访问$this.

PHP 5.4,已添加支持使用$thisin Closures.


小智 7

问题在于,包括$thisuse()不允许将其包含在声明中。

但是,如果您不包含它,那么它会正常工作。

所以问题不在于 use 语句是否存在,而在于是否$this存在于use

这应该有效(@参见https://3v4l.org/smvPt):

class Foo{
    private $a;
    function getAnon(){
        $b = 1;
        return function() use ($b) { 
            echo $b;
            echo $this->a;
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

这不应该:

class Foo{
    private $a;
    function getAnon(){
        $b = 1;
        return function() use ($this, $b) { 
            echo $b;
            echo $this->a;
        };    
    }
}
Run Code Online (Sandbox Code Playgroud)

我想本质上$this是隐式捕获的。


小智 5

你可以使用这个:

class Foo
{
  public function bar()
  {
    $obj = $this;
    return function() use ($obj)
    {
        //$obj->DoStuff();
        echo "in closure\n";
    };
  }
 }
Run Code Online (Sandbox Code Playgroud)