2010-09-15 72 views
11

我想从封闭内引用一个对象的私有变量。下面的代码似乎工作,但它抱怨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 

回答

14

编辑注意到,这个答案最初是为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"); 
+0

嘿 - 山寨;-) – DMI 2010-09-15 22:53:20

+0

@戴夫实际上,我是写之前,我看了你的答案。无论如何,你+1作为解决方案:p – Artefacto 2010-09-15 23:24:43

+0

heh。快速的并行开发。感谢+1,并且以比我更加努力的方式返回实物! :-) – DMI 2010-09-15 23:31:09

2

瓶盖都没有的$thisself概念 - 它们不依赖于该对象的方式。这意味着,你将不得不通过use子句来传递变量...是这样的:

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

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

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

+0

这是不正确的,至少不是5.4。见:http://php.net/manual/en/closure.bindto.php – GuyPaddock 2017-06-20 04:28:47

4

这是可能开始在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. 
+1

只是为了澄清,这将工作也''私人函数findMe()'? – 2014-08-15 07:29:21