从闭包中访问私有变量

Posted

技术标签:

【中文标题】从闭包中访问私有变量【英文标题】: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

【问题讨论】:

【参考方案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::bind:***.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;
;

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

【讨论】:

那不正确,至少在 5.4 中不正确。见:php.net/manual/en/closure.bindto.php【参考方案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()也有效吗?

以上是关于从闭包中访问私有变量的主要内容,如果未能解决你的问题,请参考以下文章

函数中的私有变量和特权方法

私有变量

JavaScript 闭包

两种创建私有变量私有方法的方法

JS闭包应用-私有变量柯里化偏函数

javaScript 递归 闭包 私有变量