在 PHP 中的匿名函数中访问对象的私有/受保护属性

发布于 2024-11-15 23:04:38 字数 564 浏览 4 评论 0原文

我正在尝试通过匿名函数转储对象私有属性的元素 - 当然我可以通过许多其他方式实现这一点,但这突出了一个我无法立即解决的 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();

I'm trying to dump elements of an object's private property through an anonymous function - of course I could achieve this in any number of other ways, but this highlights a PHP conundrum I can't solve off the top of my head, short of $foo = $this and using $foo - but THAT won't give me the private stuff, so... suggestions ?

Sample code:

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();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半窗疏影 2024-11-22 23:04:38

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

但是,您可以通过将匿名方法设置为类方法(这不是您所要求的,但它可能是一个实用的解决方案)或显式从 $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);
    }
}

I believe there is absolutely no way to do directly what you propose.

However, you can work around it either by making the anonymous method a class method (this is not what you asked for, but it could be a practical solution) or pulling everything you need out of $this explicitly and passing the extracted values into the function:

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);
    }
}
溇涏 2024-11-22 23:04:38

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

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

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

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);
    }
}

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

You can hack around the limitation by creating a wrapper that utilizes Reflection to allow you to access all properties and methods. You can use it like this then:

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

Here a sample implementation of the wrapper, taken from 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);
    }
}

Obviously the above implementation doesn't cover all aspects (e.g. it can't use magic properties and methods).

欢你一世 2024-11-22 23:04:38

正如您自己所说,它是私人的,因此无法访问。

您可以:

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

As you said yourself, it is private and therefore in accessible.

You can:

  • Pass $this->payload as a parameter to the anonymous function.
  • Create a method in the class and use it instead.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文