क्या PHP में सरणियों को मूल्य के रूप में या नए चर के संदर्भ में कॉपी किया जाता है, और जब फ़ंक्शन के लिए पास किया जाता है?


259

1) जब कोई सरणी किसी विधि या फ़ंक्शन के तर्क के रूप में पारित की जाती है, तो क्या यह संदर्भ द्वारा पारित किया जाता है, या मूल्य से?

2) जब एक चर को एक सरणी प्रदान करते हैं, तो नया चर मूल सरणी का एक संदर्भ है, या यह नई प्रति है?
यह करने के बारे में क्या:

$a = array(1,2,3);
$b = $a;

के लिए $bएक संदर्भ है $a?



3
@MarlonJerezIsla: यदि आप फ़ंक्शन के अंदर इसे संशोधित करते हैं तो ऐरे को केवल क्लोन किया जाता है। अभी भी अन्य भाषाओं से आ रहा है, यह अजीब लगता है।
user276648

जवाबों:


276

अपने प्रश्न के दूसरे भाग के लिए, मैनुअल का ऐरे पेज देखें , जिसमें लिखा है (उद्धृत) :

सरणी असाइनमेंट में हमेशा मूल्य प्रतिलिपि शामिल होती है। एक संदर्भ को संदर्भ द्वारा कॉपी करने के लिए संदर्भ ऑपरेटर का उपयोग करें।

और दिए गए उदाहरण:

<?php
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 is changed,
             // $arr1 is still array(2, 3)

$arr3 = &$arr1;
$arr3[] = 4; // now $arr1 and $arr3 are the same
?>


पहले भाग के लिए, सुनिश्चित करने का सबसे अच्छा तरीका कोशिश करना है ;-)

कोड के इस उदाहरण पर विचार करें:

function my_func($a) {
    $a[] = 30;
}

$arr = array(10, 20);
my_func($arr);
var_dump($arr);

यह इस उत्पादन दे देंगे:

array
  0 => int 10
  1 => int 20

जो इंगित करता है कि फ़ंक्शन ने "बाहर" सरणी को संशोधित नहीं किया है जो एक पैरामीटर के रूप में पारित किया गया था: यह एक प्रतिलिपि के रूप में पारित किया गया है, और संदर्भ नहीं।

यदि आप चाहते हैं कि यह संदर्भ द्वारा पारित हो, तो आपको फ़ंक्शन को संशोधित करना होगा, इस तरह से:

function my_func(& $a) {
    $a[] = 30;
}

और आउटपुट बन जाएगा:

array
  0 => int 10
  1 => int 20
  2 => int 30

जैसा कि, इस बार, सरणी को "संदर्भ द्वारा" पारित किया गया है।


संदर्भ को समझने में संकोच न करें मैनुअल का समझाया गया भाग: इसे आपके कुछ प्रश्नों का उत्तर देना चाहिए;;


$ a = & $ this-> a जैसी किसी चीज़ के बारे में क्या। $ अब एक संदर्भ है और यह-> ए?
फ्रैंक

1
जैसा कि आप उपयोग कर रहे हैं &, हाँ, यह चाहिए - php.net/manual/en/…
पास्कल मार्टिन

1
पवित्र गाय, मैं विश्वास नहीं कर सकता कि यह समस्या मेरे पास थी ... यह एक सबक होना चाहिए, हमेशा
ऑफिंग

2
हाय पास्कल, मैंने पाया कि कोस्टा कोंटोस का उत्तर अधिक सटीक प्रतीत होता है। मैं उसकी खोज की पुष्टि करने के लिए एक सरल त्वरित परीक्षण करता हूं। gist.github.com/anonymous/aaf845ae354578b74906 क्या आप उसकी खोज पर भी टिप्पणी कर सकते हैं?
चोक यान चेंग

1
यह वह समस्या है जो मुझे भी हो रही थी: सोचा कि यह नेस्टेड सरणियों के बारे में कुछ अजीब था, लेकिन यह वास्तव में था कि PHP में सरणी असाइनमेंट कैसे काम करता है।
जेरेमी सूची

120

आपके पहले प्रश्न के संबंध में, सरणी को संदर्भ द्वारा पारित किया गया है UNLESS द्वारा यह आपके द्वारा कॉल की जा रही विधि / फ़ंक्शन के भीतर संशोधित किया गया है। यदि आप विधि / फ़ंक्शन में सरणी को संशोधित करने का प्रयास करते हैं, तो इसकी एक प्रति पहले बनाई जाती है, और उसके बाद केवल प्रतिलिपि संशोधित की जाती है। इससे ऐसा प्रतीत होता है कि मान वास्तव में नहीं होने पर सरणी को मान से पास किया गया है।

उदाहरण के लिए, इस पहले मामले में, भले ही आप संदर्भ द्वारा $ my_array को स्वीकार करने के लिए अपने कार्य को परिभाषित नहीं कर रहे हैं (पैरामीटर परिभाषा में & वर्ण का उपयोग करके), यह अभी भी संदर्भ द्वारा पारित हो जाता है (यानी: आप मेमोरी बर्बाद नहीं करते हैं एक अनावश्यक प्रतिलिपि के साथ)।

function handle_array($my_array) {  

    // ... read from but do not modify $my_array
    print_r($my_array);

    // ... $my_array effectively passed by reference since no copy is made
}

हालाँकि यदि आप सरणी को संशोधित करते हैं, तो इसकी एक प्रति पहले बनाई जाती है (जो अधिक मेमोरी का उपयोग करती है लेकिन आपके मूल सरणी को अप्रभावित छोड़ देती है)।

function handle_array($my_array) {

    // ... modify $my_array
    $my_array[] = "New value";

    // ... $my_array effectively passed by value since requires local copy
}

FYI करें - इसे "आलसी कॉपी" या "कॉपी-ऑन-राइट" के रूप में जाना जाता है।


8
यह एक सुपर रोचक जानकारी है! लगता है कि यह सच है; लेकिन मैं इस तथ्य का समर्थन करने वाला कोई भी आधिकारिक दस्तावेज नहीं ढूंढ सका। हमें यह भी जानना होगा कि PHP के कौन से संस्करण इस आलसी प्रतिलिपि अवधारणा का समर्थन करते हैं। किसी को भी अधिक जानकारी है?
मारियो अवध

8
अपडेट, कुछ आधिकारिक दस्तावेज पाए गए, फिर भी यह जानने की जरूरत है कि PHP का कौन सा संस्करण आलसी कॉपी का समर्थन करता है (वे इसे मैनुअल में "कॉपी ऑन राइट" कहते हैं): php.net/manual/en/internals2.variables.intro.php
मारियो अवाड

7
यह पूरी तरह से PHP वर्चुअल मशीन का कार्यान्वयन निर्णय है, और भाषा का हिस्सा नहीं है - यह वास्तव में प्रोग्रामर को दिखाई नहीं देता है। प्रदर्शन के कारणों के लिए कॉपी-ऑन-राइट की सिफारिश की जाती है, लेकिन एक कार्यान्वयन जो हर सरणी को कॉपी करता है, प्रोग्रामर के दृष्टिकोण से कोई अंतर नहीं है, इसलिए हम कह सकते हैं कि भाषा शब्दार्थ पास-दर-मूल्य निर्दिष्ट करते हैं।
सुपरफ़ास्ट

14
@Superfly निश्चित रूप से एक फर्क पड़ता है जब मैं जानना चाहता हूं कि क्या मैं अपने 100MB सरणी को स्मृति से बाहर चलाने के बिना दर्जनों कार्यों के ढेर के माध्यम से पारित कर सकता हूं! आप सही हो सकते हैं कि यह शब्दार्थ पास-दर-मूल्य को कॉल करने के लिए अभी भी सही है, लेकिन शब्दावली पर इस तरह के क्विबल्स को छोड़कर, यहां वर्णित "कार्यान्वयन विस्तार" निश्चित रूप से वास्तविक दुनिया में PHP प्रोग्रामर के लिए महत्वपूर्ण है।
मार्क अमेरी

3
इसके बारे में एक और विचित्रता है, जो प्रदर्शन के बारे में सोचते समय कॉपी-ऑन-राइट के बारे में और भी महत्वपूर्ण बनाता है। आप सोच सकते हैं कि संदर्भ द्वारा सरणियों को पास करना मूल्य से गुजरने की तुलना में स्मृति को बचाता है (यदि आप कॉपी-ऑन-राइट के बारे में नहीं जानते थे) लेकिन इसका वास्तव में विपरीत प्रभाव हो सकता है! यदि सरणी को बाद में मान से (अपने स्वयं के या तीसरे पक्ष के कोड द्वारा) पास कर दिया जाता है , तो PHP को एक पूर्ण प्रतिलिपि बनानी होगी या यह अब संदर्भ गणना को ट्रैक नहीं कर सकता है! यहाँ अधिक: stackoverflow.com/questions/21974581/…
दान राजा

80

टी एल; डॉ

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 प्राप्त करें! तो यह एक गैर-एम्परसेंड परम से पढ़ने के रूप में लगभग स्मृति खाती है ।


एक स्मृति रिसाव के डिबग में मुझे कुछ घंटे बचाया!
रागन डेज़्स 20

2
Kosta Kontos: यह इतना महत्वपूर्ण प्रश्न है कि आपको इसे स्वीकृत उत्तर के रूप में चिह्नित करना चाहिए। उस ने कहा, @nevvermind: महान निबंध, लेकिन कृपया एक शीर्ष TL; DR अनुभाग शामिल करें।
अविद्युतीकरण

1
@nevvermind: मैं एक संक्षिप्त ग्रूप नहीं हूं, मुख्य अंतर यह है कि निष्कर्ष आमतौर पर एक लेख के अंत में दिखाई देते हैं, जबकि टीएल? डीआर उन लोगों के लिए पहली पंक्ति के रूप में प्रकट होता है, जिन्हें लंबे विश्लेषण के माध्यम से जाने के बजाय केवल संक्षिप्त उत्तर की आवश्यकता होती है। । आपका शोध अच्छा है और यह केवल $ 00.02 की आलोचना नहीं है।
अवेलेवलर

1
आप सही हे। मैंने शीर्ष पर निष्कर्ष रखा है। लेकिन मैं अभी भी लोगों को किसी भी निष्कर्ष पर पहुंचने से पहले पूरी बात पढ़ने में आलसी होने से रोकना चाहूंगा । चीजों के क्रम को बदलने में परेशान करने के लिए स्क्रॉल करना हमारे लिए बहुत आसान है।
नेवरमाइंड

1
मुझे लगता है कि PHP ने अधिक कुशल वर्षों के बाद प्राप्त किया है क्योंकि आपके कोडपैड उदाहरण बहुत कम संख्या देते हैं :)
drzaus

14

डिफ़ॉल्ट रूप से

  1. आदिम मूल्य द्वारा पारित किए जाते हैं। जावा के बिना, स्ट्रिंग PHP में आदिम है
  2. आदिम की सरणियाँ मूल्य द्वारा पारित की जाती हैं
  3. वस्तुओं को संदर्भ से पारित किया जाता है
  4. वस्तुओं के एरे को मान (सरणी) द्वारा पारित किया जाता है लेकिन प्रत्येक वस्तु को संदर्भ द्वारा पारित किया जाता है।

    <?php
    $obj=new stdClass();
    $obj->field='world';
    
    $original=array($obj);
    
    
    function example($hello) {
        $hello[0]->field='mundo'; // change will be applied in $original
        $hello[1]=new stdClass(); // change will not be applied in $original
        $
    }
    
    example($original);
    
    var_dump($original);
    // array(1) { [0]=> object(stdClass)#1 (1) { ["field"]=> string(5) "mundo" } } 

नोट: एक अनुकूलन के रूप में, हर एक मूल्य को संदर्भ के रूप में पारित किया जाता है जब तक कि फ़ंक्शन के अंदर संशोधित नहीं किया जाता है। यदि इसे संशोधित किया गया है और मान को संदर्भ द्वारा पारित किया गया है, तो इसकी प्रतिलिपि बनाई गई है और प्रतिलिपि संशोधित की गई है।


4
यह उत्तर शीर्ष पर + 1'ed होना चाहिए। इसमें एक अस्पष्ट गच्चा होता है जिसमें अन्य उत्तरों का उल्लेख नहीं होता है: "4 - वस्तुओं के एरे को मान (सरणी) द्वारा पारित किया जाता है लेकिन प्रत्येक वस्तु को संदर्भ द्वारा पारित किया जाता है।" मैं उस एक के कारण अपना सिर खुजला रहा था!
अगस्टिन

@ मैगलन विमानों को पहले मेरे लिए भी रेट किया जाना चाहिए, आप मुझे उन वस्तुओं की परेशानी को स्पष्ट करें जो मेरे पास थी। क्या किसी वस्तु को दो सरणी चर (मूल और प्रतिलिपि) में से एक में किसी सरणी में संशोधित करने का कोई तरीका है?
fede72bari

5

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

function test(&$array) {
    $array['new'] = 'hey';
}

$a = $array(1,2,3);
// prints [0=>1,1=>2,2=>3]
var_dump($a);
test($a);
// prints [0=>1,1=>2,2=>3,'new'=>'hey']
var_dump($a);

आपके दूसरे प्रश्न में, $bइसका संदर्भ नहीं है $a, बल्कि इसकी एक प्रति है $a

पहले उदाहरण की तरह, आप $aनिम्नलिखित करके संदर्भ ले सकते हैं :

$a = array(1,2,3);
$b = &$a;
// prints [0=>1,1=>2,2=>3]
var_dump($b);
$b['new'] = 'hey';
// prints [0=>1,1=>2,2=>3,'new'=>'hey']
var_dump($a);

1

यह धागा थोडा पुराना है लेकिन यहाँ कुछ ऐसा है जो अभी आया:

इस कोड को आज़माएं:

$date = new DateTime();
$arr = ['date' => $date];

echo $date->format('Ymd') . '<br>';
mytest($arr);
echo $date->format('Ymd') . '<br>';

function mytest($params = []) {
    if (isset($params['date'])) {
        $params['date']->add(new DateInterval('P1D'));
    }
}

http://codepad.viper-7.com/gwPYMw

ध्यान दें कि $ params पैरामीटर के लिए कोई amp नहीं है और अभी भी यह $ arr ['date'] के मूल्य को बदलता है। यह वास्तव में यहाँ अन्य सभी स्पष्टीकरणों से मेल नहीं खाता है और मैंने अब तक क्या सोचा था।

अगर मैं $ params ['तारीख'] ऑब्जेक्ट को क्लोन करता हूं, तो दूसरी आउटपुट तिथि समान रहती है। अगर मैं इसे एक स्ट्रिंग पर सेट करता हूं तो यह आउटपुट को प्रभावित नहीं करता है।


3
सरणी की प्रतिलिपि बनाई गई है, लेकिन यह एक गहरी प्रतिलिपि नहीं है । इसका अर्थ है कि संख्या और तारों जैसे आदिम मूल्यों को $ परम में कॉपी किया जाता है, लेकिन ऑब्जेक्ट के लिए, ऑब्जेक्ट को क्लोन किए जाने के बजाय संदर्भ को कॉपी किया जाता है। $ गिरफ्तारी $ तिथि का संदर्भ है, और इसलिए प्रतिलिपि बनाई गई सरणी $ params है। इसलिए जब आप $ params ['date'] पर एक फ़ंक्शन कहते हैं, जो इसके मूल्य को बदल देता है, तो आप $ arr ['date'] और $ date भी बदल रहे हैं। जब आप $ params ['date'] को एक स्ट्रिंग में सेट करते हैं, तो आप $ params के संदर्भ को $ date के साथ कुछ और के साथ बदल रहे हैं।
इजेग

1

जवाबों में से एक का विस्तार करने के लिए, बहुआयामी सरणियों की भी उपमाओं को मूल्य द्वारा पारित किया जाता है जब तक कि संदर्भ द्वारा स्पष्ट रूप से पारित नहीं किया जाता है।

<?php
$foo = array( array(1,2,3), 22, 33);

function hello($fooarg) {
  $fooarg[0][0] = 99;
}

function world(&$fooarg) {
  $fooarg[0][0] = 66;
}

hello($foo);
var_dump($foo); // (original array not modified) array passed-by-value

world($foo);
var_dump($foo); // (original array modified) array passed-by-reference

परिणाम है:

array(3) {
  [0]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(2)
    [2]=>
    int(3)
  }
  [1]=>
  int(22)
  [2]=>
  int(33)
}
array(3) {
  [0]=>
  array(3) {
    [0]=>
    int(66)
    [1]=>
    int(2)
    [2]=>
    int(3)
  }
  [1]=>
  int(22)
  [2]=>
  int(33)
}

0

PHP सरणियों में डिफ़ॉल्ट रूप से मान से कार्यों के लिए पारित किया जाता है, जब तक कि आप स्पष्ट रूप से संदर्भ द्वारा उन्हें पारित नहीं करते हैं, जैसा कि निम्नलिखित स्निपेट दिखाता है:

$foo = array(11, 22, 33);

function hello($fooarg) {
  $fooarg[0] = 99;
}

function world(&$fooarg) {
  $fooarg[0] = 66;
}

hello($foo);
var_dump($foo); // (original array not modified) array passed-by-value

world($foo);
var_dump($foo); // (original array modified) array passed-by-reference

यहाँ उत्पादन है:

array(3) {
  [0]=>
  int(11)
  [1]=>
  int(22)
  [2]=>
  int(33)
}
array(3) {
  [0]=>
  int(66)
  [1]=>
  int(22)
  [2]=>
  int(33)
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.