可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
$ 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
The following code (similar to example at https://bugs.php.net/bug.php?id=49543):
class Foo { public function bar() { return function() use ($this) { echo "in closure\n"; }; } }
fails with:
PHP Fatal error: Cannot use $this as lexical variable
Yet according to the PHP docs and a comment on that bug report from Rasmus Lerdorf, using $this in anonymous functions was added as of PHP 5.4. What am I doing wrong?
回答1:
So it seems $this can be used simply if it isn't specified via the "use" keyword.
The following echoes 'bar':
class Foo { private $foo = 'bar'; public function bar() { return function() { echo $this->foo; }; } } $bar = (new Foo)->bar(); $bar();
This was reported in the php-internals mailing list and is apparently overhang from 5.3's lack of support for this functionality:
http://marc.info/?l=php-internals&m=132592886711725
回答2:
I don't know the answer to your actual question (ie Why can't you do it), but I can give you a work around: Use a temporary copy of $this
and use()
that instead:
class Foo { public function bar() { $that = $this; return function() use($that) { print_r($that); }; } }
I've just tested it, and this does work.
回答3:
In PHP 5.3
if you are using a Closure inside of a class, the Closure
will not have access to $this
.
In PHP 5.4
, support has been added for the usage of $this
in Closures
.
回答4:
The issue is that including $this in the use() statement is not allowed. However if you don't include it then it will work fine.
So the issue isn't whether the use statement is present, it's whether $this is present in the use statement.
This should work:
class Foo{ private $a; function getAnon(){ $b = 1; return function() use ($b) { echo $b; echo $this->a; } } }
This shouldn't:
class Foo{ private $a; function getAnon(){ $b = 1; return function() use ($this, $b) { echo $b; echo $this->a; } } }
I suppose essentially $this is implicitly captured.
回答5:
I'm using PHP 5.4.25 and actually I am able to use class variables in a closure also with the use
keyword as shown below:
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();
Output:
I am a private bar I am a protected bar I am a public bar
回答6:
It may be a bug, but there is no sense in explicit binding $this
to a function anyway as it is automatically bound:
PHP documentation says
As of PHP 5.4.0, when declared in the context of a class, the current class is automatically bound to it, making $this available inside of the function's scope.
Thus, fatal error is thrown in today's version of PHP:
From PHP 7.1, these variables must not include superglobals, $this, or variables with the same name as a parameter.