मैं किसी अज्ञात फ़ंक्शन के माध्यम से किसी ऑब्जेक्ट की निजी संपत्ति के तत्वों को डंप करने का प्रयास कर रहा हूं - बेशक मैं इसे किसी भी अन्य तरीकों से प्राप्त कर सकता हूं, लेकिन यह एक 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();
5
Wagemage 17 जून 2011, 17:47
1
डुप्ली ऑफ -सार्वजनिक संपत्ति, इसलिए बंद करने के लिए मतदान नहीं।
 – 
outis
13 फरवरी 2012, 16:24

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);
    }
}
3
Jon 17 जून 2011, 17:52
दरअसल - आपका कोड दर्शाता है कि मैंने इस विशेष मामले में क्या किया। ओह ठीक है, यह सामान्य रूप से एक दिलचस्प समस्या है - उम्मीद कर रहा था कि उस मुद्दे को हल करने का एक तरीका था जिससे मैं अनजान था। जवाब के लिए धन्यवाद :)
 – 
Wagemage
17 जून 2011, 18:02
+1 मैंने इसके साथ एक उत्तर पोस्ट किया इससे पहले कि मुझे एहसास हुआ कि आपने इसे पहले ही कह दिया है। सबसे सरल समाधान अक्सर सबसे अच्छा होता है।
 – 
Andrew Curioso
17 जून 2011, 18:10

आप एक आवरण बनाकर सीमा के आसपास हैक कर सकते हैं जो प्रतिबिंब का उपयोग करके आपको सभी गुणों और विधियों तक पहुंचने की अनुमति देता है। आप इसे तब इस तरह इस्तेमाल कर सकते हैं:

$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
NikiC 17 जून 2011, 17:57
दिलचस्प रूप से बुराई :) बेशक शायद मैं उत्पादन के लिए क्या नहीं करूँगा, लेकिन यह समस्या को हल करता है - धन्यवाद
 – 
Wagemage
17 जून 2011, 18:05

जैसा कि आपने स्वयं कहा, यह निजी है और इसलिए सुलभ है।

आप ऐसा कर सकते हैं:

  • अनाम फ़ंक्शन के पैरामीटर के रूप में $this->payload पास करें।
  • कक्षा में एक विधि बनाएं और इसके बजाय इसका इस्तेमाल करें।
1
Shay Ben Moshe 17 जून 2011, 17:54