$ 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
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
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.
You can use this:
class Foo
{
public function bar()
{
$obj = $this;
return function() use ($obj)
{
//$obj->DoStuff();
echo "in closure\n";
};
}
}
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 (@see https://3v4l.org/smvPt):
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.
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
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
.