代码之家  ›  专栏  ›  技术社区  ›  Kendall Hopkins

从闭包中访问私有变量

  •  12
  • Kendall Hopkins  · 技术社区  · 16 年前

    我试图从闭包中引用对象的私有变量。下面的代码似乎可以工作,但它会抱怨 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
    
    3 回复  |  直到 13 年前
        1
  •  14
  •   Community Mohan Dere    9 年前

    按注释编辑, 这个答案原本是为 第5.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" );
    
        2
  •  4
  •   Ari Asulin    13 年前

    这可以从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.
    
        3
  •  2
  •   DMI    16 年前

    闭包没有 $this 或 self --它们不会以那种方式与物体相连。这意味着您必须通过 use

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

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

    推荐文章