Доступ к закрытым переменным из закрытия
Я пытаюсь ссылаться на частную переменную объекта изнутри закрытия. Код, как представляется, работает, но он жалуется Fatal error: Cannot access self:: when no class scope is active in test.php on line 12
и Fatal error: Using $this when not in object context in test.php on line 20
.
Любые идеи о том, как выполнить одни и те же результаты, используя закрытие, сохраняя частные переменные и не создавая вспомогательные функции (побеждая всю идею частной переменной).
class MyClass
{
static private $_var1;
private $_var2;
static function setVar1( $value )
{
$closure = function () use ( $value ) {
self::$_var1 = $value;
};
$closure();
}
function setVar2( $value )
{
$closure = function () use ( $value ) {
$this->_var2 = $value;
};
$closure();
}
}
MyClass::setVar1( "hello" ); //doesn't work
$myclass = new MyClass;
$myclass->setVar2( "hello" ); //doesn't work
Ответы
Ответ 1
Изменить, чтобы отметить, этот ответ изначально был предназначен для PHP5.3 и ранее, теперь это возможно. Для получения текущей информации см. этот ответ.
Это невозможно. В частности, закрытие не имеет связанной области, поэтому они не могут получить доступ к частным и защищенным членам.
Однако вы можете использовать ссылки:
<?php
class MyClass
{
static private $_var1;
private $_var2;
static function setVar1( $value )
{
$field =& self::$_var1;
$closure = function () use ( $value, &$field ) {
$field = $value;
};
$closure();
}
function setVar2( $value )
{
$field =& $this->_var2;
$closure = function () use ( $value, &$field ) {
$field = $value;
};
$closure();
}
}
MyClass::setVar1( "hello" );
$myclass = new MyClass;
$myclass->setVar2( "hello" );
Ответ 2
Это возможно, начиная с PHP 5.4.0
class test {
function testMe() {
$test = new test;
$func = function() use ($test) {
$test->findMe(); // Can see protected method
$test::findMeStatically(); // Can see static protected method
};
$func();
return $func;
}
protected function findMe() {
echo " [find Me] \n";
}
protected static function findMeStatically() {
echo " [find Me Statically] \n";
}
}
$test = new test;
$func = $test->testMe();
$func(); // Can call from another context as long as
// the closure was created in the proper context.
Ответ 3
Закрытия не имеют понятия $this
или self
- они не привязаны к объектам таким образом. Это означает, что вам придется передавать переменные через предложение use
... что-то вроде:
$_var1 =& self::$_var1;
$closure = function() use ($value, &$_var1) {
$_var1 = $value;
};
$_var2 =& $this->_var2;
$closure = function() use ($value, &$_var2) {
$_var2 = $value;
};
Я не тестировал вышеуказанный код, но считаю, что это правильно.