2012-02-24 8 views
6

जब मैं कोड झटका चलाएँ:सरणी तत्व बदलते समय एक सरणी तत्व (पहले असाइन-बाय-रेफरेंस के बाद) के मान द्वारा आवंटित एक चर क्यों बदलता है?

$var[0] = 'a'; 
$tmp = $var; 
$var[0] = 'b'; 
var_dump($tmp); 

उत्पादन होता है:

$var[0] = 'a'; 
$foo = & $var[0]; # added line 
$tmp = $var; 
$var[0] = 'b'; 
var_dump($tmp); 

उत्पादन हो जाता है::

array(1) { [0]=> &string(1) "b" } 

array(1) { [0]=> string(1) "a" } 

इस प्रकार जब मैं एक पंक्ति जोड़ें

यदि मैं किसी सरणी के तत्व $var[0] के संदर्भ में एक चर $foo असाइन करता हूं, तो $tmp को $var के मान के अनुसार निर्दिष्ट किया गया है? ऐसा क्यों होता है?

+0

ध्यान दें कि विभिन्न "पास-बाय- *" शब्द केवल फ़ंक्शन तर्कों पर लागू होते हैं।यहाँ कोई असाइनमेंट पास नहीं है, केवल असाइनमेंट। – outis

उत्तर

2

यह brought up in the docs है, पृष्ठ पर comments में से एक वास्तव में इस विशिष्ट व्यवहार का उल्लेख करता है।

3

अस्वीकरण: मैं इसके लिए एक स्पष्ट संदर्भ नहीं ढूंढ पाया है, इसलिए मैं अधिकतर यहां पर जोर दे रहा हूं।

एक नियमित संदर्भ प्रतीक तालिका के माध्यम से काम करता है। जब एक चर और एक मूल्य बनाने, दोनों बहुत की तरह स्थानीय प्रतीक तालिका में जमा हो जाती है:

$bar =& $foo; 

+------------+-------+ 
| symbol  | value | 
+------------+-------+ 
| $foo, $bar | "bar" | 
+------------+-------+ 
:

$foo = "bar"; 

+--------+-------+ 
| symbol | value | 
+--------+-------+ 
| $foo | "bar" | 
+--------+-------+ 

जब एक संदर्भ बनाया जाता है, यह बस मेज पर एक ही मूल्य के लिए एक और प्रतीक कहते हैं

सरणी कुंजी अलग ढंग से हालांकि जमा हो जाती है:

$var[0] = 'a'; 

+--------+-----------------+ 
| symbol | value   | 
+--------+-----------------+ 
| $var | array(0 => 'a') | 
+--------+-----------------+ 

वहाँ $var के लिए प्रतीक तालिका में एक प्रविष्टि है, लेकिन सरणी के अंदर मूल्यों को व्यक्तिगत रूप में संदर्भित नहीं हैं प्रतीक तालिका।

$foo =& $var[0]; 

+--------+------------------+ 
| symbol | value   | 
+--------+------------------+ 
| $var | array(0 => %REF) | 
| $foo | %REF    | 
| %REF | 'a'    | 
+--------+------------------+ 
: क्या मैं यह अनुमान लगा जब मूल्य 'a' ( $var[0] में संग्रहीत) के लिए एक संदर्भ बनाने में हो रहा होगा कि मूल्य 'a' सरणी से अलग है $var और $var[0] ही जहां 'a' संग्रहीत किया जाता है के नए स्थान के लिए एक संदर्भ हो जाता है

मुझे लगता है कि प्रतीक तालिका का आंतरिक कार्यान्वयन सरणी कुंजी के प्रत्यक्ष संदर्भ बनाने की अनुमति नहीं देता है, इसलिए यह एक सरणी तत्व का संदर्भ बनाने का एकमात्र तरीका है।

तो जब $tmp को $var को कॉपी, संदर्भ इसके साथ की नकल की है:

$tmp = $var; 

+--------+------------------+ 
| symbol | value   | 
+--------+------------------+ 
| $var | array(0 => %REF) | 
| $foo | %REF    | 
| %REF | 'a'    | 
| $tmp | array(0 => %REF) | 
+--------+------------------+ 

तब, जब मूल्य $var[0] को संदर्भित करता है बदल रहा है, यह %REF का मूल्य, जो दोनों $tmp और $var का उल्लेख बदल जाता है।

जैसा कि मैंने कहा था, यह आंतरिक रूप से क्या हो रहा है इसका सटीक स्पष्टीकरण हो सकता है या नहीं, लेकिन यह सिद्धांत को दर्शाता है।

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^