2011-03-29 14 views
34

सी ++ में यदि आप किसी फ़ंक्शन में बड़ी सरणी पास करते हैं, तो आपको इसे संदर्भ द्वारा पास करना होगा, ताकि यह स्मृति को बर्बाद करने वाले नए फ़ंक्शन पर प्रतिलिपि न हो। यदि आप इसे संशोधित नहीं करना चाहते हैं तो आप इसे संदर्भ संदर्भ से पास कर दें।PHP में संदर्भ द्वारा पास का उपयोग करना कब अच्छा है?

क्या कोई भी यह सत्यापित कर सकता है कि संदर्भ से गुज़रने से मुझे PHP में भी स्मृति मिल जाएगी। मुझे पता है कि PHP सी ++ जैसे संदर्भों के लिए पते का उपयोग नहीं करता है इसलिए मैं थोड़ा अनिश्चित हूं। यह सवाल है।

+1

बस एक सी ++ संबंधित नोट: कार्यों में पारित किए गए Arrays वास्तव में पॉइंटर्स हैं, इसलिए संदर्भ पारित करना उनके लिए अनावश्यक है और वास्तव में ऐसा नहीं करता जो आपको लगता है कि यह करता है। यद्यपि पूरी तरह से कॉन्स्ट पर सहमत हैं! – Aaron

उत्तर

52

निम्नलिखित वस्तुओं, जैसा कि यह पहले से ही कहा गया है। यदि आप पारित मूल्य को संशोधित करने की योजना बनाते हैं, तो संदर्भ द्वारा सरणी और स्केलर मानों को पास करने से केवल आपको स्मृति मिल जाएगी, क्योंकि PHP एक प्रति-परिवर्तन (उर्फ कॉपी-ऑन-राइट) नीति का उपयोग करता है। उदाहरण के लिए:

# $array will not be copied, because it is not modified. 
function foo($array) { 
    echo $array[0]; 
} 

# $array will be copied, because it is modified. 
function bar($array) { 
    $array[0] += 1; 
    echo $array[0] + $array[1]; 
} 

# This is how bar shoudl've been implemented in the first place. 
function baz($array) { 
    $temp = $array[0] + 1; 
    echo $temp + $array[1]; 
} 


# This would also work (passing the array by reference), but has a serious 
#side-effect which you may not want, but $array is not copied here. 
function foobar(&$array) { 
    $array[0] += 1; 
    echo $array[0] + $array[1]; 
} 

संक्षेप में:

  • आप एक समारोह के अंदर इसे संशोधित करने पर एक बहुत बड़ा सरणी और योजना पर काम कर रहे हैं, तो आप वास्तव में यह की नकल की हो रही करने से रोकने के लिए एक संदर्भ का उपयोग करना चाहिए , जो प्रदर्शन को गंभीरता से कम कर सकता है या आपकी स्मृति सीमा को भी समाप्त कर सकता है।

  • यदि यह टालने योग्य है (हालांकि छोटे सरणी या स्केलर मान हैं), तो मैं हमेशा किसी भी दुष्प्रभाव के साथ कार्यात्मक-शैली दृष्टिकोण का उपयोग करता हूं, क्योंकि जैसे ही आप संदर्भ द्वारा कुछ पास करते हैं, आप कभी भी सुनिश्चित नहीं हो सकते फ़ंक्शन कॉल के बाद कौन सा पास वैरिएबल हो सकता है, जो कभी-कभी खराब और कठिन-खोजने वाली बग का कारण बन सकता है।

  • आईएमएचओ स्केलर मान संदर्भ द्वारा कभी पारित नहीं किया जाना चाहिए, क्योंकि प्रदर्शन प्रभाव आपके कोड में पारदर्शिता के नुकसान को उचित ठहराने के लिए इतना बड़ा नहीं हो सकता है।

+0

स्पष्टीकरण के लिए धन्यवाद और +1। चूंकि मुझे कॉपी-ऑन-चेंज पर इंफोस खोजने में कठिनाइयां थीं: "लिखने पर प्रतिलिपि" के लिए देखें (google) और आपको http://php.net/manual/en/internals2.variables.intro.php पर जाना होगा – dennis

8

PHP में:

  • वस्तुओं संदर्भ द्वारा पारित कर रहे हैं - हमेशा
  • सरणियों और scalars डिफ़ॉल्ट रूप से मूल्य द्वारा पारित कर रहे हैं; और फ़ंक्शन की घोषणा में & का उपयोग करके by reference पारित किया जा सकता है।


अपने प्रश्न, पीएचपी सी/C++ कि उसी तरह से निपटने के नहीं है के प्रदर्शन भाग के लिए; आप निम्न आलेख पढ़ना चाहिए: Do not use PHP references


1. या कि क्या हम आम तौर पर कहना है - भले ही वह "पूरी तरह से सच" नहीं है - करता है देखने के लिए लागू नहीं Objects and references

+0

मैं थोड़ा उलझन में हूं .. क्या इसका मतलब है कि मैं एक सिंगलटन क्लास बनाने और साइट के प्रत्येक विज़िटर को संदर्भित करने में सक्षम हूं, बजाय उनमें से प्रत्येक के लिए डेटाबेस पूछताछ? (सभी आगंतुक एक ही डेटा का अनुरोध कर रहे हैं) – sdadffdfd

+3

PHP में, आपके पास सिंगलटन "प्रति सर्वर" नहीं होगा - लेकिन एक सिंगलटन "एक स्क्रिप्ट के निष्पादन"। प्रत्येक उपयोगकर्ता के पास स्क्रिप्ट का अपना अलग, अलग, निष्पादन होगा - जिसका अर्थ है कि प्रत्येक व्यक्ति की अपनी मेमोरी स्पेस होगी; स्क्रिप्ट के निष्पादन के लिए आपका सिंगलटन एक सिंगलटन होगा; और लिपि के प्रत्येक निष्पादन में आपके सिंगलटन का अपना उदाहरण होगा। –

+0

यह दुखद है .. PHP में ऐसी सुविधा रखने के लिए बहुत अच्छा होगा। धन्यवाद। – sdadffdfd

8

संक्षिप्त उत्तर उपयोग संदर्भ जब आप कार्यक्षमता है कि वे उपलब्ध कराने की जरूरत है। स्मृति उपयोग या गति के संदर्भ में उनके बारे में मत सोचो। संदर्भ द्वारा पास हमेशा धीमा होने जा रहा है यदि चर केवल पढ़ने के लिए है।

सबकुछ वस्तुओं सहित मूल्य से गुजरता है। हालांकि, यह है जो पारित ऑब्जेक्ट के को संभालता है, इसलिए लोग अकसर गलती से इसे संदर्भ द्वारा कॉल करते हैं क्योंकि ऐसा लगता है।

फिर यह कौन सी कार्यक्षमता प्रदान करता है? यदि आप इस तरह की कार्यक्षमता की जरूरत है (सबसे अधिक बार तुम नहीं), तो एक संदर्भ का उपयोग

class Bar {} 
$bar = new Bar(); 

function by_val($o) { $o = null; } 
function by_ref(&$o) { $o = null; } 

by_val($bar); // $bar is still non null 
by_ref($bar); // $bar is now null 

तो: यह आपको बुला रहा दायरे में चर संशोधित करने की क्षमता देता है। अन्यथा, बस मूल्य से गुजरें।

कार्य है कि इस तरह दिखेगा:

$foo = modify_me($foo); 

कभी कभी पारित-दर-संदर्भ के लिए अच्छा उम्मीदवार हैं, लेकिन यह बिल्कुल स्पष्ट समारोह को संशोधित करता है कि चर में पारित किया जाना चाहिए। (और यदि ऐसा कोई कार्य उपयोगी होता है, तो अक्सर ऐसा इसलिए होता है क्योंकि इसे वास्तव में अपने स्वयं के निजी डेटा को संशोधित करने वाले कुछ वर्गों का हिस्सा होना चाहिए।)

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