2010-11-30 6 views
5

कुछ शोध करने के बाद, मैं अंत में एक प्रश्न के उत्तर में आया, जिसे मैं जल्द ही यहां पूछने के लिए आया था; आप PHP में __get और __set जादू विधियों के माध्यम से सरणी के साथ कैसे काम करते हैं? जब भी मैं $object->foo['bar'] = 42; जैसे किसी चीज़ का उपयोग करके मूल्य निर्धारित करने का प्रयास कर रहा था, तो यह चुपचाप इसे छोड़ देता था।सरणी के साथ __set का उपयोग हल, लेकिन क्यों?

वैसे भी, उत्तर सरल है; __get विधि को संदर्भ द्वारा वापस लौटने की आवश्यकता है। और इसके सामने एक एम्पर्सेंड फेंकने के बाद, यह सुनिश्चित करता है कि यह काम करता है।

मेरा प्रश्न वास्तव में, क्यों है? मुझे समझ में नहीं आ रहा है कि यह क्यों काम कर रहा है। __get संदर्भ द्वारा लौटने से __set बहुआयामी सरणी के साथ काम करता है?

संपादित करें: जिस तरह से चल रहा है, पीएचपी 5.3.1

+0

यह पीएचपी 5.2.x बनाने में लगता है __get एक संदर्भ लौटने में मदद नहीं करता है। – Vlad

उत्तर

3

इस विशेष मामले में, __set वास्तव में कॉल नहीं किया जा रहा है।

$tmp = $object->__get('foo'); 
$tmp['bar'] = 42 

तो __get एक संदर्भ वापस नहीं किया था, तो इसके बजाय मूल वस्तु के 'बार' सूचकांक 42 देने की है, तो आप कर रहे हैं: आप को तोड़ने यह क्या हो रहा है, यह एक थोड़ा और अधिक अर्थपूर्ण होनी चाहिए की 'बार' इंडेक्स को मूल ऑब्जेक्ट की कॉपी करें।

+0

धन्यवाद ** डीन **; समझ गया :) – Dan

4

PHP में से जब आप एक समारोह से कोई मान आप यह है कि मूल्य की एक प्रति बनाने (जब तक यह एक वर्ग है) पर विचार कर सकते हैं। के मामले में जब तक आप उस वास्तविक चीज़ को वापस नहीं लौटते जब तक आप संपादित करना नहीं चाहते हैं, तो सभी बदलाव एक प्रतिलिपि में किए जाते हैं जिसे तब त्याग दिया जाता है।

+0

आह, इसलिए '__set' कहने से पहले, मान को सेट करने की प्रक्रिया में,' __get' को ऑब्जेक्ट वेरिएबल के अस्तित्व को पुनः प्राप्त करने (या जांचने) के लिए बुलाया जाता है? – Dan

+1

'$ ऑब्जेक्ट-> foo ['bar'] = 42; 'कभी कॉल नहीं किया जाता है। सेट को तब कहा जाता है जब आप '$ object-> key = $ value' जैसे कुछ करते हैं, लेकिन जब आप '$ ऑब्जेक्ट-> कुंजी [$ key2] = $ value' नहीं करते हैं। ऐसा इसलिए है क्योंकि '$ ऑब्जेक्ट-> कुंजी [$ key2]' '__get' का उपयोग करके हल किया गया है और फिर बदला गया है। तो आप इसे '$ magic_get_value = $ value' जैसे सोच सकते हैं। –

2

शायद और अधिक स्पष्ट:

//PHP will try to interpret this: 
$object->foo['bar'] = 42 

//The PHP interpreter will try to evaluate first 
$object->foo 

//To do this, it will call 
$object->__get('foo') 
// and not __get("foo['bar']"). __get() has no idea about ['bar'] 

//If we have get defined as &__get(), this will return $_data['foo'] element 
//by reference. 
//This array element has some value, like a string: 
$_data['foo'] = 'value'; 

//Then, after __get returns, the PHP interpreter will add ['bar'] to that 
//reference. 
$_data['foo']['bar'] 

//Array element $_data['foo'] becomes an array with one key, 'bar'. 
$_data['foo'] = array('bar' => null) 

//That key will be assigned the value 42 
$_data['foo']['bar'] = 42 

//42 will be stored in $_data array because __get() returned a reference in that 
//array. If __get() would return the array element by value, PHP would have to 
//create a temporary variable for that element (like $tmp). Then we would make 
//that variable an array with $tmp['bar'] and assign 42 to that key. As soon 
//as php would continue to the next line of code, that $tmp variable would 
//not be used any more and it will be garbage collected. 
संबंधित मुद्दे