Почему я не могу использовать $ this как лексическую переменную в PHP 5.5.4?

$ 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, использование $ this в анонимных функциях было добавлено с PHP 5.4. Что я делаю не так?

Related of "Почему я не могу использовать $ this как лексическую переменную в PHP 5.5.4?"

Таким образом, кажется, что $ this можно использовать просто, если он не указан с помощью ключевого слова «use».

Следующий эхо-бар:

 class Foo { private $foo = 'bar'; public function bar() { return function() { echo $this->foo; }; } } $bar = (new Foo)->bar(); $bar(); 

Об этом сообщается в списке рассылки php-internals и, по-видимому, нависает от отсутствия поддержки 5.3 для этой функции:

http://marc.info/?l=php-internals&m=132592886711725

Я не знаю ответа на ваш реальный вопрос (т. Е. Почему вы не можете это сделать), но я могу дать вам работу: используйте временную копию $this и use() которая вместо этого:

 class Foo { public function bar() { $that = $this; return function() use($that) { print_r($that); }; } } 

Я только что протестировал его, и это работает.

В PHP 5.3 если вы используете Closure внутри класса , Closure не будет иметь доступ к $this .

В PHP 5.4 добавлена ​​поддержка для использования $this в Closures .

Проблема в том, что включение $ this в оператор use () не допускается. Однако, если вы не включите его, он будет работать нормально.

Таким образом, проблема заключается не в том, присутствует ли оператор использования, а в том, существует ли значение $ this в инструкции use.

Это должно работать:

 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; } } } 

Я предполагаю, что в принципе это неявно захвачено.

Я использую 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 

Это может быть ошибка, но нет смысла в явной привязке $this к функции в любом случае, поскольку она автоматически связана:

Документация PHP

Начиная с PHP 5.4.0, когда объявляется в контексте класса, текущий класс автоматически привязывается к нему, делая $ this доступным внутри области действия.

Таким образом, фатальная ошибка возникает в сегодняшней версии PHP:

Из PHP 7.1 эти переменные не должны включать суперглобалы, $ this или переменные с тем же именем, что и параметр.