Php 从闭包中访问私有变量

Php 从闭包中访问私有变量,php,scope,closures,Php,Scope,Closures,我试图从闭包中引用对象的私有变量。下面的代码似乎可以工作,但它会抱怨致命错误:第12行的test.php中没有活动的类作用域时无法访问self::和致命错误:第20行的test.php中没有对象上下文时使用$this 如何使用闭包实现相同的结果,同时保持变量的私有性,而不使用辅助函数(破坏私有变量的整体概念) 编辑注释,这个答案最初是针对PHP5.3和更早版本的,现在可以了。有关当前信息,请参阅 这是不可能的。特别是,闭包没有关联的作用域,因此它们无法访问私有和受保护的成员 但是,您可以使用引

我试图从闭包中引用对象的私有变量。下面的代码似乎可以工作,但它会抱怨
致命错误:第12行的test.php中没有活动的类作用域时无法访问self::和
致命错误:第20行的test.php中没有对象上下文时使用$this

如何使用闭包实现相同的结果,同时保持变量的私有性,而不使用辅助函数(破坏私有变量的整体概念)


编辑注释,这个答案最初是针对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" );

闭包没有
$this
self
的概念——它们不以那种方式绑定到对象。这意味着您必须通过
use
子句传递变量。。。比如:

$_var1 =& self::$_var1;
$closure = function() use ($value, &$_var1) {
  $_var1 = $value;
};

$_var2 =& $this->_var2;
$closure = function() use ($value, &$_var2) {
  $_var2 = $value;
};

我还没有测试过上面的代码,但我相信它是正确的。

这可以从PHP5.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.

@戴夫,其实我在读你的答案之前就已经写了。不管怎样,对你来说+1是一个解决方案:呸。快速并行开发。谢谢你的+1,并以同样的方式回报你,因为你比我付出了更多的努力!:-)您也可以使用
Closure::bind
,就像我在这里的问题一样:只是为了澄清一下,这对
私有函数findMe()
也有效吗?这是不正确的,至少在5.4中是不正确的。见:
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.