$ 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. Что я делаю не так?
Таким образом, кажется, что $ this можно использовать просто, если он не указан с помощью ключевого слова «use».
Следующий эхо-бар:
class Foo { private $foo = 'bar'; public function bar() { return function() { echo $this->foo; }; } } $bar = (new Foo)->bar(); $bar();
Об этом сообщается в списке рассылки php-internals и, по-видимому, нависает от отсутствия поддержки 5.3 для этой функции:
Я не знаю ответа на ваш реальный вопрос (т. Е. Почему вы не можете это сделать), но я могу дать вам работу: используйте временную копию $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 или переменные с тем же именем, что и параметр.