टी एल; डॉ
a) विधि / फ़ंक्शन केवल सरणी तर्क => निहित (आंतरिक) संदर्भ
b) पढ़ता है विधि / फ़ंक्शन सरणी तर्क को संशोधित करता है => मान
c) विधि / फ़ंक्शन सरणी तर्क स्पष्ट रूप से एक संदर्भ (एक एम्परसेंड के साथ) के रूप में चिह्नित किया जाता है => स्पष्ट (उपयोगकर्ता-भूमि) संदर्भ
या यह:
- गैर-एम्परसेंड सरणी परम : संदर्भ द्वारा पारित; लेखन संचालन सरणी की एक नई प्रतिलिपि को बदल देता है, प्रतिलिपि जो पहले लिखने पर बनाई जाती है;
- एम्परसेंड सरणी परम : संदर्भ द्वारा पारित; लेखन कार्य मूल सरणी को बदल देते हैं।
याद रखें - PHP गैर-एम्परसेंड सरणी परम के लिए आपके द्वारा लिखे जाने वाले क्षण को एक मूल्य-कॉपी करता है । इसका copy-on-write
मतलब है। मैं आपको इस व्यवहार का C स्रोत दिखाना पसंद करूंगा, लेकिन यह वहां डरावना है। बेहतर उपयोग xdebug_debug_zval () ।
पास्कल मार्टिन सही था। कोस्टा कोनटोस और भी अधिक था।
उत्तर
निर्भर करता है।
दीर्घ संस्करण
मुझे लगता है कि मैं इसे अपने लिए लिख रहा हूं। मुझे एक ब्लॉग या कुछ और चाहिए ...
जब भी लोग संदर्भ (या संकेत, उस बात के लिए) की बात करते हैं, तो वे आमतौर पर एक लॉगोमैची में समाप्त होते हैं (बस इस धागे पर !)।
PHP एक आदरणीय भाषा होने के नाते, मुझे लगा कि मुझे भ्रम में जोड़ना चाहिए (भले ही यह उपरोक्त उत्तरों का सारांश हो)। क्योंकि, हालांकि दो लोग एक ही समय में सही हो सकते हैं, आप एक उत्तर में एक साथ अपने सिर को फोड़ने से बेहतर हैं।
सबसे पहले, आपको पता होना चाहिए कि यदि आप एक काले और सफेद तरीके से जवाब नहीं देते हैं तो आप एक पेडेंट नहीं हैं । चीजें "हां / नहीं" से अधिक जटिल हैं।
जैसा कि आप देखेंगे, संपूर्ण बाई-वैल्यू / बाय-रेफरेंस चीज बहुत कुछ इस बात से संबंधित है कि आप अपने तरीके / फ़ंक्शन स्कोप में उस एरे के साथ क्या कर रहे हैं: इसे पढ़ रहे हैं या इसे संशोधित कर रहे हैं?
PHP क्या कहता है? (उर्फ "परिवर्तन-वार")
मैनुअल इस (जोर मेरा) का कहना है:
डिफ़ॉल्ट रूप से, फ़ंक्शन तर्क मान द्वारा पारित किए जाते हैं (ताकि यदि फ़ंक्शन के भीतर तर्क का मान बदल जाए , तो यह फ़ंक्शन के बाहर नहीं बदला जाता है)। किसी फ़ंक्शन को अपने तर्कों को संशोधित करने की अनुमति देने के लिए , उन्हें संदर्भ द्वारा पारित किया जाना चाहिए ।
किसी फ़ंक्शन के लिए तर्क को हमेशा संदर्भ द्वारा पारित किया जाता है, फ़ंक्शन परिभाषा में तर्क नाम के लिए एक एम्परसेंड (&) को प्रस्तुत करना
जहां तक मैं बता सकता हूं, जब बड़े, गंभीर, ईमानदार-से-ईश्वर प्रोग्रामर संदर्भों के बारे में बात करते हैं, तो वे आमतौर पर उस संदर्भ के मूल्य को बदलने की बात करते हैं । और वास्तव में मैनुअल क्या बात करता है hey, if you want to CHANGE the value in a function, consider that PHP's doing "pass-by-value"
:।
एक और मामला है कि वे उल्लेख नहीं करते हैं, हालांकि: क्या होगा अगर मैं कुछ भी नहीं बदलता हूं - बस पढ़ें?
यदि आप किसी सरणी को किसी विधि से पास करते हैं जो स्पष्ट रूप से एक संदर्भ को चिह्नित नहीं करती है, और हम उस सरणी को फ़ंक्शन के दायरे में नहीं बदलते हैं। उदाहरण के लिए:
<?php
function readAndDoStuffWithAnArray($array)
{
return $array[0] + $array[1] + $array[2];
}
$x = array(1, 2, 3);
echo readAndDoStuffWithAnArray($x);
मेरे साथी यात्री पढ़िए।
PHP वास्तव में क्या करता है? (उर्फ "स्मृति-वार")
वही बड़े और गंभीर प्रोग्रामर, जब वे और भी अधिक गंभीर हो जाते हैं, तो वे संदर्भों के संबंध में "मेमोरी ऑप्टिमाइजेशन" के बारे में बात करते हैं। तो PHP करता है। क्योंकि PHP is a dynamic, loosely typed language, that uses copy-on-write and reference counting
, इसीलिए ।
यह विभिन्न कार्यों के लिए विशाल सरणियों को पारित करने के लिए आदर्श नहीं होगा, और PHP उनमें से प्रतियां बनाने के लिए (यही "पास-बाय-वैल्यू" करता है, आखिरकार):
<?php
// filling an array with 10000 elements of int 1
// let's say it grabs 3 mb from your RAM
$x = array_fill(0, 10000, 1);
// pass by value, right? RIGHT?
function readArray($arr) { // <-- a new symbol (variable) gets created here
echo count($arr); // let's just read the array
}
readArray($x);
खैर अब, अगर यह वास्तव में पास-बाय-वैल्यू था, तो हमारे पास कुछ 3mb + RAM होगा, क्योंकि उस सरणी की दो प्रतियां हैं , है ना?
गलत। जब तक हम $arr
चर को नहीं बदलते , तब तक यह एक संदर्भ, स्मृति-वार है । तुम बस इसे नहीं देखते। यही कारण है कि जब आंतरिक और स्पष्ट (एम्परसेंड के साथ) के बीच अंतर करने के लिए PHP उपयोगकर्ता-भूमि संदर्भों का उल्लेख करता है। &$someVar
तथ्य
इसलिए, when an array is passed as an argument to a method or function is it passed by reference?
मैं तीन (हाँ, तीन) मामलों के साथ आया था :
ए) विधि / फ़ंक्शन केवल सरणी तर्क को पढ़ता है
ख) विधि / फ़ंक्शन सरणी तर्क को संशोधित करता है
ग) विधि / फ़ंक्शन सरणी तर्क को स्पष्ट रूप से एक संदर्भ के रूप में चिह्नित किया गया है (एक के साथ) एम्परसेंड)
सबसे पहले, देखते हैं कि सरणी वास्तव में कितनी मेमोरी खाती है ( यहां चलाएं ):
<?php
$start_memory = memory_get_usage();
$x = array_fill(0, 10000, 1);
echo memory_get_usage() - $start_memory; // 1331840
वह कई बाइट्स। महान।
a) विधि / कार्य केवल सरणी तर्क को पढ़ता है
अब एक फंक्शन बनाते हैं जो केवल उक्त एरे को एक तर्क के रूप में पढ़ता है और हम देखेंगे कि रीडिंग लॉजिक में कितनी मेमोरी है:
<?php
function printUsedMemory($arr)
{
$start_memory = memory_get_usage();
count($arr); // read
$x = $arr[0]; // read (+ minor assignment)
$arr[0] - $arr[1]; // read
echo memory_get_usage() - $start_memory; // let's see the memory used whilst reading
}
$x = array_fill(0, 10000, 1); // this is 1331840 bytes
printUsedMemory($x);
वाना लगता है? मुझे 80 मिले! अपने लिए देखें । यह वह भाग है जिसे PHP मैनुअल छोड़ देता है। यदि $arr
परम वास्तव में पारित-मूल्य था, तो आपको 1331840
बाइट्स के समान कुछ दिखाई देगा । ऐसा लगता है कि $arr
एक संदर्भ की तरह व्यवहार करता है, है ना? क्योंकि यह ऐसा इसलिए है है एक आंतरिक एक - एक संदर्भ।
बी) विधि / फ़ंक्शन सरणी तर्क को संशोधित करता है
अब, उस परम से लिखते हैं , बजाय उससे पढ़ने के:
<?php
function printUsedMemory($arr)
{
$start_memory = memory_get_usage();
$arr[0] = 1; // WRITE!
echo memory_get_usage() - $start_memory; // let's see the memory used whilst reading
}
$x = array_fill(0, 10000, 1);
printUsedMemory($x);
फिर से, अपने लिए देखें , लेकिन, मेरे लिए, वह 1331840 होने के काफी करीब है। इसलिए इस मामले में, सरणी को वास्तव में कॉपी किया जा रहा है $arr
।
ग) विधि / कार्य सरणी तर्क स्पष्ट रूप से एक संदर्भ के रूप में चिह्नित किया गया है (एम्परसेंड के साथ)
अब देखते हैं कि एक स्पष्ट संदर्भ के लिए एक लिखित ऑपरेशन कितना मेमोरी लेता है ( यहां चलाएं ) - फ़ंक्शन हस्ताक्षर में एम्परसेंड पर ध्यान दें:
<?php
function printUsedMemory(&$arr) // <----- explicit, user-land, pass-by-reference
{
$start_memory = memory_get_usage();
$arr[0] = 1; // WRITE!
echo memory_get_usage() - $start_memory; // let's see the memory used whilst reading
}
$x = array_fill(0, 10000, 1);
printUsedMemory($x);
मेरी शर्त है कि आप अधिकतम 200 प्राप्त करें! तो यह एक गैर-एम्परसेंड परम से पढ़ने के रूप में लगभग स्मृति खाती है ।