Why can I not use $this as a lexical variable in PHP 5.5.4?

匿名 (未验证) 提交于 2019-12-03 01:58:03

问题:

$ 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.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!