Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/239.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么我不能在PHP5.5.4中使用$this作为词法变量?_Php - Fatal编程技术网

为什么我不能在PHP5.5.4中使用$this作为词法变量?

为什么我不能在PHP5.5.4中使用$this作为词法变量?,php,Php,以下代码(类似于中的示例): 在以下情况下失败: class Foo { public function bar() { return function() use ($this) { echo "in closure\n"; }; } } 然而,根据PHP文档和Rasmus Lerdorf对该bug报告的评论,在匿名函数中使用$this是从PHP5.4开始添加的。我做错了什么?我不知道你实际问题的

以下代码(类似于中的示例):

在以下情况下失败:

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

然而,根据PHP文档和Rasmus Lerdorf对该bug报告的评论,在匿名函数中使用$this是从PHP5.4开始添加的。我做错了什么?

我不知道你实际问题的答案(即为什么你不能这么做),但我可以给你一个解决办法:使用
$this
的临时副本和
Use()
的临时副本:

PHP Fatal error:  Cannot use $this as lexical variable

我刚刚对它进行了测试,这确实有效。

因此,如果没有通过“use”关键字指定,似乎$this可以简单地使用

以下是“酒吧”的回音:

class Foo
{
    public function bar()
    {
        $that = $this;
        return function() use($that)
        {
            print_r($that);
        };
    }
}
php内部邮件列表中报告了这一点,这显然是由于5.3缺乏对该功能的支持:


我使用的是PHP5.4.25,实际上我能够在闭包中使用类变量,还可以使用
use
关键字,如下所示:

class Foo
{
    private $foo = 'bar';

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

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

$bar();
输出:

class Foo
{
    private $_privateBar = 'private bar';
    protected $_protectedBar = 'protected bar';
    public $_publicBar = 'public bar';

    public function bar()
    {
        $prefix = 'I am a ';

        return function() use ($prefix) {
            echo $prefix . $this->_privateBar . "\n";
            echo $prefix . $this->_protectedBar . "\n";
            echo $prefix . $this->_publicBar . "\n";
        };
    }
}

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

$bar();

问题是不允许在
use()
语句中包含
$this

然而,如果你不包括它,那么它将工作良好

因此,问题不在于use语句是否存在,而在于
$this
是否存在于
use
语句中

这应该会起作用(@see):

这不应该:

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

我假设本质上,
$this
是隐式捕获的。

PHP5.3
中,如果在类内部使用,则
闭包将无法访问
$this


PHP5.4
中,添加了对
闭包中使用
$this
的支持,这可能是一个bug,但将
$this
显式绑定到函数没有任何意义,因为它是自动绑定的:

从PHP5.4.0开始,当在类的上下文中声明时,当前 类自动绑定到它,使$this在 函数的作用域

因此,在今天的PHP版本中会抛出致命错误:

在PHP7.1中,这些变量不得包括超全局变量、$this或与参数同名的变量


我知道,这是一个老问题,但也许谷歌的人会发现:

出现错误的原因是,不能在同一个闭包中使用已定义的变量名作为词法变量

由于在PHP5.5及更高版本中,您可以在闭包中访问
$this
,因此已存在名为
$this
的变量

下面是另一个示例,您将得到相同的错误:

class Foo{
    private $a;
    function getAnon(){
        $b = 1;
        return function() use ($this, $b) { 
            echo $b;
            echo $this->a;
        };    
    }
}
如您所见,
$item
已经用作闭包参数,因此您不能使用它作为词法变量。

您可以使用:

$item = "Test 1";
$myFnc = function($item) use ($item) {
    ...
}
$myFnc("Test 2");

检查以确保您使用的是来自web服务器的相同版本的PHP。它通常与Bash中的第一条路径不同。使用
phpinfo()
。根据中的一个快速测试,这在5.5.5中仍然是一样的,甚至…也许Rasmus在这一点上错了…?编辑:或者在他说这句话的时候,它本打算放在5.4中(懒得去查,不知道当时5.4是否已经过时了),但他们又删除了它,因为它在实现的方式上造成了额外的问题。@Brad值得一提,但我用cli测试了这一点。问题不是
use
关键字隐含地阻止了
$this
的使用,而是为什么
use($prefix,$this)
,如果在您的示例中使用,将是不必要的/无效的。在我看来,克里斯蒂亚诺的回答就像是一个强调您不准确陈述的意愿,您写道:“因此,如果没有指定“use”关键字,那么似乎可以使用$this。”根据克里斯蒂亚诺的代码(我亲自尝试过,它就像一个符咒)你的答案是错误的。你应该考虑把这个标记为正确答案。啊,我没有意识到他对我的答案而不是我的问题作出了回应。事实上,开头的句子可能是误导性的。它是针对原始问题的,其中只有这一个变量是通过的,而<代码>函数()使用()。
无效。已修复。将对象分配给变量是通过引用完成的,所以$this
临时副本实际上是$this
$引用。但是,为什么我们不能在use语句中使用
$this
,但我们可以使用通过引用分配的变量呢?答案很好,您能提供源代码吗?在在5.4中,这意味着5.3不支持$this-inside-enclosures?感谢PHP7用户,这个答案仍然是绝对正确的。这个答案应该在顶部!尽管仍然存在于7中
class Foo{
    private $a;
    function getAnon(){
        $b = 1;
        return function() use ($this, $b) { 
            echo $b;
            echo $this->a;
        };    
    }
}
$item = "Test 1";
$myFnc = function($item) use ($item) {
    ...
}
$myFnc("Test 2");
class Foo
{
  public function bar()
  {
    $obj = $this;
    return function() use ($obj)
    {
        //$obj->DoStuff();
        echo "in closure\n";
    };
  }
 }