मैं दूसरे दिन How to changing value in $array2 without referring $array1? पर इस प्रतीत होता है कि यह बहुत ही सरल सवाल आया है, लेकिन जितना अधिक मैंने देखा उतना ही यह अजीब लग रहा था कि यह वास्तव में इरादे से काम कर रहा है। इसके बाद मैंने निम्नलिखित के आउटपुट से उत्पन्न ओपोड्स को देखना शुरू कर दिया।संदर्भ बग द्वारा असाइन करें
$array1 = array(2, 10);
$x = &$array1[1];
$array2 = $array1;
$array2[1] = 22;
echo $array1[1]; // Outputs 22
यह मेरे लिए पागल के बाद से array2 केवल array1 और कुछ भी है कि एक सरणी के लिए होता अन्य की सामग्री को प्रभावित नहीं करना चाहिए की एक प्रति होना चाहिए लगता है। बेशक यदि आप दूसरी पंक्ति पर टिप्पणी करते हैं तो अंतिम पंक्ति उम्मीद की तरह 10 को प्रतिबिंबित करेगी।
आगे देखकर मैं एक अच्छी साइट देख सकता हूं जो मुझे ओपोडोड दिखाता है जो PHP Vulcan Logic Dumper का उपयोग करता है। उपर्युक्त कोड द्वारा उत्पन्न ओपोडोड यहां दिए गए हैं।
Finding entry points
Branch analysis from position: 0
Return found
filename: /in/qO86H
function name: (null)
number of ops: 11
compiled vars: !0 = $array1, !1 = $x, !2 = $array2
line # * op fetch ext return operands
---------------------------------------------------------------------------------
3 0 > INIT_ARRAY ~0 2
1 ADD_ARRAY_ELEMENT ~0 10
2 ASSIGN !0, ~0
4 3 FETCH_DIM_W $2 !0, 1
4 ASSIGN_REF !1, $2
5 5 ASSIGN !2, !0
6 6 ASSIGN_DIM !2, 1
7 OP_DATA 22, $6
8 8 FETCH_DIM_R $7 !0, 1
9 ECHO $7
10 > RETURN 1
ये opcodes यहाँ महान http://php.net/manual/en/internals2.opcodes.php दस्तावेज नहीं कर रहे हैं, लेकिन मैं अंग्रेजी में विश्वास करते हैं opcodes निम्नलिखित कर रहे हैं। लाइन से ... किसी और की तुलना में मेरे लिए अधिक हो सकता है।
- रेखा 3: हम सरणी को इसके पहले मान के साथ प्रारंभ करते हैं और फिर इसे $ array1 को सौंपने से पहले इसमें 10 जोड़ते हैं।
- रेखा 4: केवल एक लेख प्राप्त करें? सरणी से मूल्य और इसे $ x के संदर्भ में असाइन करें।
- रेखा 5: $ array1 से $ array2 सेट करें।
- रेखा 6: 1. od_data की सरणी अनुक्रमणिका प्राप्त करें मैं अनुमान लगा रहा हूं कि इसे 22 पर सेट किया गया है हालांकि $ 6 कभी वापस नहीं आया है। OD_DATA में बिल्कुल कोई प्रलेखन नहीं है और मैंने देखा है कि कहीं भी एक ओपोड के रूप में सूचीबद्ध नहीं है।
- रेखा 8: $ 1 के 1 सूचकांक से केवल पढ़ने योग्य मान प्राप्त करें और इसे प्रतिबिंबित करें।
ओपकोड्स के माध्यम से भी काम करना मुझे यकीन नहीं है कि यह गलत कहां जा रहा है। मुझे ऑपकोड पर दस्तावेज़ीकरण की कमी महसूस हो रही है और उनके साथ काम करने में मेरी अनुभवहीनता मुझे यह पता लगाने से रोक रही है कि यह कहां गलत हो रहा है।
संपादित करें 1:
के रूप में पहली टिप्पणी सरणियों में माइक से कहा संदर्भ जब वे कॉपी कर रहे हैं स्थिति संरक्षित है। यहां http://php.net/manual/en/language.types.array.php#104064 से लिंक किए गए सरणी आलेख में किसी स्थान के साथ प्रलेखन देखा जा सकता है। यह मजाकिया पर्याप्त चेतावनी नहीं माना जाता है। मेरे लिए आश्चर्य की बात यह है कि यदि यह सच है तो संदर्भ कोड इस कोड के लिए संरक्षित नहीं है जैसा आप उम्मीद करेंगे।
$array1 = array(2, 10);
$x = &$array1;
$array2 = $array1;
$array2[1] = 22;
echo $array1[1]; // Output is 10
तो ऐसा लगता है कि यह केवल होता है जब आप कोशिश करते हैं और इस कार्यक्षमता भी अधिक भ्रमित कर रही है संदर्भ द्वारा एकल तत्वों आवंटित।
PHP केवल व्यक्तिगत रूप से असाइन किए जाने पर सरणी अनुक्रमणिका की स्थिति को संरक्षित क्यों करता है?
संपादित करें 2:
मैं कुछ आज HHVM का उपयोग कर परीक्षण किया था और HHVM कोड के पहले स्निप-यह संभालती है आप कैसे लगता है कि यह होगा। मुझे PHP पसंद है लेकिन एचएचवीएम ज़ेंड इंजन पर बेहतर और बेहतर दिख रहा है।
क्यों http://php.net/manual/en/language.types.array.php#104064 देखें। "साझा" डेटा साझा रहता है। –
यह मेरे लिए पागल लगता है क्योंकि आप वास्तव में सरणी संरचना को बदल रहे हैं जब आप संदर्भ के इसके हिस्सों को संदर्भित करते हैं। इसके अलावा यदि आप लाइन 2 से [1] को हटाते हैं तो डेटा साझा डेटा समान नहीं रहता है, इसलिए यह पूरी तरह से सत्य नहीं है। – mschuett
आरंभिक असाइनमेंट सिर्फ एक उपनाम है। एक बार जब आप उन्हें स्वतंत्र संचालन के साथ छेड़छाड़ करना शुरू नहीं करते हैं जैसे '... []' कि उन्हें अलग करने के लिए मजबूर किया जाता है। यह निश्चित रूप से "अप्रत्याशित" है, लेकिन मैं इसे "पागल" कहने के लिए अब तक नहीं जाऊंगा। हालांकि मैं इस बात की खुशी से खुश हूं कि इसे बनाया जाने पर बहुत अच्छा विकल्प नहीं था, और तब से PHP इसके साथ फंस गया है। –