Доступ к закрытым / защищенным свойствам объекта в анонимной функции в PHP - PullRequest
5 голосов
/ 17 июня 2011

Я пытаюсь сбросить элементы частного свойства объекта с помощью анонимной функции - конечно, я мог бы достичь этого множеством других способов, но это выдвигает на первый план загадку 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();

Ответы [ 3 ]

3 голосов
/ 17 июня 2011

Вы можете обойти ограничение, создав оболочку, которая использует Reflection, чтобы позволить вам получить доступ ко всем свойствам и методам. Вы можете использовать его следующим образом:

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

Очевидно, что приведенная выше реализация не охватывает все аспекты (например, она не может использовать магические свойства и методы).

3 голосов
/ 17 июня 2011

Я считаю, что нет абсолютно никакого способа сделать то, что вы предлагаете напрямую.

Однако вы можете обойти это, либо сделав анонимный метод методом класса (это не то, что вы просили, но этоможет быть практическим решением) или вытащить все необходимое из $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 голос
/ 17 июня 2011

Как вы сами сказали, это приватно и поэтому доступно.

Вы можете:

  • Передать $ this-> payload в качестве параметра анонимной функции.
  • Создайте метод в классе и используйте его вместо этого.
...