5

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

3 Answers 3

3

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); } } 
Sign up to request clarification or add additional context in comments.

2 Comments

Indeed - your code reflects what I ended up doing in this particular case. Oh well, it's an interesting problem in general - was hoping there was a way to address the issue I was simply unaware of. Thanks for the answer :)
+1 I posted an answer with this before I realized that you already said it. The simplest solution is often the best.
3

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).

1 Comment

Interestingly evil :) Of course probably not what I'd do for production, but it does solve the problem - thanks
1

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.