【问题标题】:Accessing private/protected properties of an object in anonymous function in PHP在 PHP 中的匿名函数中访问对象的私有/受保护属性
【发布时间】:2011-09-17 05:19:06
【问题描述】:

我试图通过匿名函数转储对象私有属性的元素 - 当然我可以通过任何其他方式实现这一点,但这突出了我无法解决的 PHP 难题,缺少 $foo = $this 并使用 $foo - 但那不会给我私人的东西,所以...建议?

示例代码:

class MyClass
{
    private $payload = Array( 'a' => 'A element', 'b' => 'B element');

    static $csvOrder = Array('b','a');

    public function toCSV(){
        $values = array_map(
            function($name) use ($this) { return $this->payload[$name]; },  
            self::$csvOrder
        );
        return implode(',',$values);
    }
}

$mc = new MyClass();
print $mc->toCSV();

【问题讨论】:

标签: php oop anonymous-function


【解决方案1】:

我相信绝对没有办法直接按照你的建议去做。

但是,您可以通过将匿名方法设为类方法(这不是您所要求的,但它可能是一个实用的解决方案)或显式地从$this 中提取您需要的所有内容并传递将值提取到函数中:

class MyClass
{
    private $payload = Array( 'a' => 'A element', 'b' => 'B element');

    static $csvOrder = Array('b','a');

    public function toCSV(){
        $payload = $this->payload;
        $values = array_map(
            function($name) use ($payload) { return $payload[$name]; },  
            self::$csvOrder
        );
        return implode(',',$values);
    }
}

【讨论】:

  • 确实 - 您的代码反映了我在这种特殊情况下最终所做的事情。哦,好吧,总的来说这是一个有趣的问题 - 希望有一种方法可以解决我根本不知道的问题。谢谢你的回答:)
  • +1 在我意识到你已经说过之前,我发布了一个答案。最简单的解决方案往往是最好的。
【解决方案2】:

您可以通过创建一个利用反射允许您访问所有属性和方法的包装器来绕过限制。你可以这样使用它:

$self = new FullAccessWrapper($this);
function () use ($self) { /* ... */ }

这里是包装器的示例实现,取自here

class FullAccessWrapper
{
    protected $_self;
    protected $_refl;

    public function __construct($self)
    {
        $this->_self = $self;
        $this->_refl = new ReflectionObject($self);
    }

    public function __call($method, $args)
    {
        $mrefl = $this->_refl->getMethod($method);
        $mrefl->setAccessible(true);
        return $mrefl->invokeArgs($this->_self, $args);
    }

    public function __set($name, $value)
    {
        $prefl = $this->_refl->getProperty($name);
        $prefl->setAccessible(true);
        $prefl->setValue($this->_self, $value);
    }

    public function __get($name)
    {
        $prefl = $this->_refl->getProperty($name);
        $prefl->setAccessible(true);
        return $prefl->getValue($this->_self);
    }

    public function __isset($name)
    {
        $value = $this->__get($name);
        return isset($value);
    }
}

显然上述实现并未涵盖所有方面(例如,它不能使用魔法属性和方法)。

【讨论】:

  • 有趣的邪恶 :) 当然可能不是我会为生产做的,但它确实解决了问题 - 谢谢
【解决方案3】:

正如你自己所说,它是私有的,因此是可访问的。

你可以:

  • 将 $this->payload 作为参数传递给匿名函数。
  • 在类中创建一个方法并使用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-13
    • 2014-10-15
    • 2013-10-02
    • 2013-07-19
    • 2013-01-05
    • 1970-01-01
    • 2019-10-06
    • 1970-01-01
    相关资源
    最近更新 更多