为什么我不能在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";
};
}
}