$ 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
以下代码(类似于https://bugs.php.net/bug.php?id=49543处的示例):
class Foo
{
public function bar()
{
return function() use ($this)
{
echo "in closure\n";
};
}
}
失败了:
PHP Fatal error: Cannot use $this as lexical variable
然而,根据PHP文档和对Rasmus Lerdorf的错误报告的评论,从PHP 5.4开始,在匿名函数中使用$ this。我做错了什么?
答案 0 :(得分:54)
所以看起来$如果没有通过“use”关键字指定,可以使用它。
以下回声'bar':
class Foo
{
private $foo = 'bar';
public function bar()
{
return function()
{
echo $this->foo;
};
}
}
$bar = (new Foo)->bar();
$bar();
这是在php-internals邮件列表中报告的,显然由于5.3缺乏对此功能的支持而过剩:
答案 1 :(得分:8)
我不知道你的实际问题的答案(即 为什么 你不能这样做),但我可以给你一个解决方法:使用一个$this
和use()
的临时副本,而不是:
class Foo
{
public function bar()
{
$that = $this;
return function() use($that)
{
print_r($that);
};
}
}
我刚试过它,这确实有效。
答案 2 :(得分:7)
在PHP 5.3
中,如果您使用 Closure类,则Closure
将无法访问$this
。
在PHP 5.4
中,添加了对$this
中Closures
的使用的支持。
答案 3 :(得分:4)
问题是不允许在use()语句中包含$ this。但是,如果你不包含它,那么它将正常工作。
所以问题不在于是否存在使用声明,而是在使用声明中是否存在$ this。
这应该有效:
class Foo{
private $a;
function getAnon(){
$b = 1;
return function() use ($b) {
echo $b;
echo $this->a;
}
}
}
这不应该:
class Foo{
private $a;
function getAnon(){
$b = 1;
return function() use ($this, $b) {
echo $b;
echo $this->a;
}
}
}
我认为基本上$这是隐含的。
答案 4 :(得分:2)
这可能是一个错误,但是在函数显式绑定$this
时没有任何意义,因为它自动绑定:
从PHP 5.4.0开始,当在类的上下文中声明时,当前 class自动绑定到它,使得$ this在里面可用 功能的范围。
因此,今天的PHP版本中会出现致命错误:
从PHP 7.1开始,这些变量不得包含superglobals,$ this或与参数同名的变量。
答案 5 :(得分:2)
我知道,这是一个老问题,但也许谷歌的某人发现了这个问题:
您收到错误的原因是,因为您无法在同一个闭包中使用已定义的变量名作为词法变量。
由于在PHP 5.5及更高版本中您可以访问闭包内的$this
,因此名称为$this
的变量已经存在。
这是另一个例子,你会得到同样的错误:
$item = "Test 1";
$myFnc = function($item) use ($item) {
...
}
$myFnc("Test 2");
正如您所看到的,$item
已被用作闭包参数,因此您可以将它作为词汇变量。
答案 6 :(得分:1)
我正在使用PHP 5.4.25,实际上我也可以使用use
关键字在闭包中使用类变量,如下所示:
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();
输出:
I am a private bar
I am a protected bar
I am a public bar
答案 7 :(得分:1)
您可以使用此:
class Foo
{
public function bar()
{
$obj = $this;
return function() use ($obj)
{
//$obj->DoStuff();
echo "in closure\n";
};
}
}