PHP 5.4 कॉल-टाइम पास-बाय-संदर्भ - आसान फिक्स उपलब्ध है?


219

क्या इस मुद्दे को आसानी से ठीक करने का कोई तरीका है या मुझे वास्तव में सभी विरासत कोड को फिर से लिखने की आवश्यकता है?

PHP Fatal error: लाइन 30 में ... कॉल-टाइम पास-बाय-रेफरेंस हटा दिया गया है

यह हर जगह होता है क्योंकि चर पूरे कोड में संदर्भ के रूप में कार्य में पारित होते हैं।


जवाबों:


344

आपको फ़ंक्शन परिभाषा में संदर्भ द्वारा कॉल को निरूपित किया जाना चाहिए, वास्तविक कॉल नहीं। चूंकि PHP ने संस्करण 5.3 में पदावनति त्रुटियों को दिखाना शुरू कर दिया है, मैं कहूंगा कि कोड को फिर से लिखना एक अच्छा विचार होगा।

प्रलेखन से :

एक फ़ंक्शन कॉल पर कोई संदर्भ संकेत नहीं है - केवल फ़ंक्शन परिभाषाओं पर। अकेले फ़ंक्शन परिभाषाएँ संदर्भ द्वारा तर्क को सही ढंग से पारित करने के लिए पर्याप्त हैं। PHP 5.3.0 के रूप में, आपको यह कहते हुए एक चेतावनी मिलेगी कि "कॉल-टाइम पास-बाय-रेफरेंस" का उपयोग करने पर पदावनत &किया जाता है foo(&$a);

उदाहरण के लिए, उपयोग करने के बजाय:

// Wrong way!
myFunc(&$arg);               # Deprecated pass-by-reference argument
function myFunc($arg) { }

उपयोग:

// Right way!
myFunc($var);                # pass-by-value argument
function myFunc(&$arg) { }

9
डिप्रेशन पीएचपी 5.0.0 के बाद से है, उस समय को E_COMPILE_WARNINGलेवल एरर देते हुए, संदर्भ के लिए: php.net/manual/en/…
hakre

5
मेरे पास यह त्रुटि थी लेकिन चर में जोड़ने के लिए & निकालने की आवश्यकता थी।
डायना

2
मैंने पुराने कोड में घटना (और $ घटना) नामक एक वस्तु के लिए उपयोग किया था, और त्रुटि संदेश को गायब करने के लिए एम्परसैंड को हटाना पड़ा।
नतालिया

1
एक डेवलपर के रूप में मेरे सभी वर्षों में वास्तव में कभी भी php का उपयोग करने की आवश्यकता नहीं है। कभी नहीं। यह ठीक वही है जिसकी मुझे तलाश थी। महान
जुआन वेलर

8
टिप्पणियों में लोगों के लिए, ध्यान दें कि & हटाने से अप्रत्याशित परिणाम हो सकते हैं क्योंकि चर में कोई भी परिवर्तन अब साझा नहीं किए जाएंगे, लेकिन केवल फ़ंक्शन स्थानीय क्षेत्र में दिखाई देंगे। इसलिए जब तक आप यह नहीं जानते कि कोड क्या करता है, मैं इसे ठीक करने की सलाह
दूंगा

8

मेरे जैसे किसी के लिए, यह पढ़ता है क्योंकि उन्हें 5.6 में एक विशाल विरासत परियोजना को अपडेट करने की आवश्यकता है: जैसा कि यहां दिए गए उत्तर बताते हैं, कोई त्वरित निर्धारण नहीं है: आपको वास्तव में समस्या की प्रत्येक घटना को मैन्युअल रूप से खोजने की आवश्यकता है, और इसे ठीक करें ।

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

इस regex का उपयोग करना:

^(?!.*function).*(\&\$)

&$फ़ंक्शन की परिभाषा नहीं है जो केवल लाइनों में होने वाली घटना के लिए प्रोजेक्ट-वाइड खोजना संभव है ।

यह अभी भी बहुत सारी गलत सकारात्मकता को बदल देता है, लेकिन यह काम को आसान बनाता है।

VSCode के खोज परिणाम ब्राउज़र के माध्यम से चलना और आपत्तिजनक पंक्तियों को सुपर आसान खोजना है: आप बस प्रत्येक परिणाम पर क्लिक करते हैं, और उन लोगों के लिए बाहर देखते हैं जो लिंटर लाल रंग को रेखांकित करते हैं। जिन्हें आपको ठीक करना है।


1
यह वही है जिसे मैं देख रहा था!
सन्नी

4
अधिक सटीक रेगेक्स मैं इस उद्देश्य के लिए उपयोग कर रहा हूं:(?<!function)[:> ][a-zA-Z0-9_]+(?<!foreach|array)\s?\([^()]*&\$
मोजो

बस phpcs का उपयोग करें, यह आपके लिए हर फ़ाइल को खोद देगा।
थॉमस चेंग

6

PHP और संदर्भ कुछ हद तक unintuitive हैं। यदि सही स्थानों पर उचित संदर्भों का उपयोग किया जाता है तो बड़े प्रदर्शन में सुधार हो सकता है या बहुत बदसूरत वर्कअराउंड और असामान्य कोड से बचा जा सकता है।

निम्नलिखित एक त्रुटि उत्पन्न करेगा:

 function f(&$v){$v = true;}
 f(&$v);

 function f($v){$v = true;}
 f(&$v);

इनमें से किसी को भी असफल नहीं होना है क्योंकि वे नीचे दिए गए नियमों का पालन कर सकते हैं, लेकिन बहुत सारी विरासत की उलझन को रोकने के लिए इसमें कोई संदेह या निष्कासन नहीं किया गया है।

यदि उन्होंने काम किया, तो दोनों में संदर्भ के लिए एक निरर्थक रूपांतरण शामिल है और दूसरे में एक निरर्थक रूपांतरण भी शामिल है जो एक स्कोप वाले निहित चर में है।

दूसरा एक संदर्भ के साथ काम करने के इरादे से कोड को पारित करने की अनुमति देने के लिए संभव हुआ करता था। यह स्थिरता के लिए बेहद बदसूरत है।

यह कुछ नहीं करेगा:

 function f($v){$v = true;}
 $r = &$v;
 f($r);

अधिक विशेष रूप से, यह संदर्भ को एक सामान्य चर में बदल देता है जैसा कि आपने संदर्भ के लिए नहीं पूछा है।

यह काम करेगा:

 function f(&$v){$v = true;}
 f($v);

यह देखता है कि आप एक गैर-संदर्भ से गुजर रहे हैं, लेकिन एक संदर्भ चाहते हैं इसलिए इसे संदर्भ में बदल दिया जाता है।

इसका मतलब यह है कि आप एक फ़ंक्शन के संदर्भ को पारित नहीं कर सकते हैं जहां एक संदर्भ स्पष्ट रूप से इसे उन कुछ क्षेत्रों में से एक बनाने के लिए नहीं पूछा जाता है जहां PHP गुजरने के प्रकारों पर सख्त है या इस मामले में मेटा प्रकार से अधिक है।

यदि आपको अधिक गतिशील व्यवहार की आवश्यकता है तो यह काम करेगा:

 function f(&$v){$v = true;}
 $v = array(false,false,false);
 $r = &$v[1];
 f($r);

यहाँ यह देखता है कि आप एक संदर्भ चाहते हैं और पहले से ही एक संदर्भ है इसलिए इसे अकेला छोड़ देता है। यह संदर्भ की श्रृंखला भी कर सकता है लेकिन मुझे इस पर संदेह है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.