2010-09-15 70 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