2011-06-17 13 views
5

Estoy tratando de volcar elementos de la propiedad privada de un objeto a través de una función anónima; por supuesto, podría lograrlo de muchas otras maneras, pero esto resalta una No puedo resolver el enigma de PHP, excepto $ foo = $ this y usando $ foo, pero ESO no me dará las cosas privadas, entonces ... ¿sugerencias?Accediendo a propiedades privadas/protegidas de un objeto en función anónima en PHP

Código de ejemplo:

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

Duplicado de ["Acceso a variables privadas desde dentro de un cierre"] (http://stackoverflow.com/q/3722394/90527), pero la respuesta de NikiC funciona para acceder a métodos no públicos, así como a propiedades no públicas, entonces no votar por el cierre. – outis

Respuesta

3

Creo que no hay absolutamente ninguna manera de hacerlo directamente lo que se propone.

Sin embargo, puede solucionarlo haciendo que el método anónimo sea un método de clase (esto no es lo que pidió, pero podría ser una solución práctica) o extraer todo lo que necesita de $this explícitamente y pasar el valores en la función:

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

De hecho, su código refleja lo que terminé haciendo en este caso particular. Oh, bueno, es un problema interesante en general, esperaba que hubiera una manera de abordar el problema que simplemente ignoraba. Gracias por la respuesta :) – Wagemage

+0

+1 He publicado una respuesta con esto antes de darme cuenta de que ya lo has dicho. La solución más simple suele ser la mejor. –

1

Como usted mismo ha dicho, es privada y por lo tanto en el acceso.

Puede:

  • Pasar $ this-> carga útil como parámetro a la función anónima.
  • Cree un método en la clase y úselo en su lugar.
3

Puede hackear la limitación creando un contenedor que utiliza Reflection para permitirle acceder a todas las propiedades y métodos. Se puede utilizar de esta manera a continuación:

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

Aquí un ejemplo de implementación de la envoltura, tomada de 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); 
    } 
} 

Es evidente que la implementación anterior no cubre todos los aspectos (por ejemplo, no puede usa propiedades y métodos mágicos).

+0

Interesantemente mal :) Por supuesto, probablemente no sea lo que haría para la producción, pero * resuelve * el problema - gracias – Wagemage

Cuestiones relacionadas