【问题标题】:Accessing private variables from within a closure从闭包中访问私有变量
【发布时间】:2011-04-12 22:50:17
【问题描述】:

我正在尝试从闭包中引用对象的私有变量。下面的代码似乎可以工作,但它抱怨Fatal error: Cannot access self:: when no class scope is active in test.php on line 12Fatal 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

【问题讨论】:

    标签: php scope closures


    【解决方案1】:

    编辑要注意,这个答案最初是为 PHP5.3 和更早的,现在可以了。有关当前信息,请参阅this answer


    这是不可能的。特别是,闭包没有关联范围,因此它们无法访问私有成员和受保护成员。

    但是,您可以使用引用:

    <?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" );
    

    【讨论】:

    • @Dave 在阅读您的答案之前,我实际上是在写它。无论如何,为你+1作为解决方案:p
    • 嘿。快速并行开发。感谢您的 +1,并以实物形式返回,因为您付出的努力比我多得多! :-)
    • 您也可以在我的问题中使用Closure::bindstackoverflow.com/q/52701638/1163000
    【解决方案2】:

    闭包没有$thisself 的概念——它们不以那种方式与对象绑定。这意味着您必须通过 use 子句传递变量...类似于:

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

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

    【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 澄清一下,这对private function findMe()也有效吗?
    猜你喜欢
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 2014-08-15
    • 2016-05-02
    • 2018-12-24
    • 2014-02-09
    • 2015-09-25
    相关资源
    最近更新 更多