2011-06-17 40 views
5

私はオブジェクトのプライベートプロパティの要素を匿名関数でダンプしようとしています。もちろんこれは他の方法でも可能ですが、 PHPの謎私は私の頭の上を解くことはできません、$ foo = $ thisと$ fooを使っていませんが、それは私に私的なものを与えません。PHPの匿名関数でオブジェクトのプライベート/プロテクトプロパティにアクセスする

サンプルコード:

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

[「閉鎖内からのプライベート変数へのアクセス」](http://stackoverflow.com/q/3722394/90527)しかし、NikiCの答えは非公開のメソッドだけでなく非公開のプロパティにもアクセスできますが、閉鎖には投票しない。 – outis

答えて

3

私はあなたが提案しているものを直接行うには方法は絶対にありません信じています。

しかし、匿名メソッドをクラスメソッド(これはあなたが求めているものではありませんが、実用的な解決策である可能性があります)または明示的に$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); 
    } 
} 
+0

確かに、あなたのコードはこの特定のケースでやったことを反映しています。まあ、それは一般的に興味深い問題です - 私は単に知らなかった問題に対処する方法があることを望んでいました。答えをありがとう:) – Wagemage

+0

+1私はあなたがすでにそれを言ったことに気付く前に、これと答えを投稿しました。最も簡単な解決策がしばしば最適です。 –

1

あなた自身が言ったように、それはプライベートでアクセス可能です。

次のことが可能です。

  • は無名関数のパラメータとしての$ this - >ペイロードを渡します。
  • クラス内にメソッドを作成し、代わりに使用します。
3

Reflectionを使用するラッパーを作成して、すべてのプロパティとメソッドにアクセスできるようにすることで、この制限を回避することができます。次に、このようにそれを使用することができます:

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

上記の実装は、例えば、それはできません(すべての側面をカバーしていません魔法のプロパティとメソッドを使用する)。

+0

興味深いことに:)もちろん、私がプロダクションのためにやるべきことではないかもしれませんが、問題を解決します - ありがとう – Wagemage