दिलचस्प पोस्ट
जब संग्रह का आदेश दिया जाता है तो क्या LINQ द्विआधारी खोज का उपयोग कर सकता है? NavBar में प्रोग्राम को एक तस्वीर कैसे सेट करें? दृश्य में प्रयुक्त PostgreSQL कॉलम बदलें विजुअल स्टूडियो में सी ++ फ़ाइल के लिए #include पदानुक्रम को प्रदर्शित करना एएसपी .नेट एमवीसी और आईई कैशिंग – हेरिएट रिस्पांस हेडर अप्रभावी Django label_tag () आउटपुट में कक्षा जोड़ें sprintf के खतरों को समझना (…) स्क्रॉल स्थिति को ट्रैक करना और उसके बारे में अन्य घटकों को सूचित करना नया टैब में हैडर स्थान हैश तालिका का समय जटिलता प्रोग्राममैटिक रूप से अनुरोध एक्सेस से संपर्क करें मैक ओएस एक्स पर एडीबी सेट करें विंडोज बैच फ़ाइल का उपयोग करते हुए कई आदेशों के साथ सिंगल लाइन Project.json में 'निर्भरताएं' और 'फ्रेमवर्कऐस्ब्लबलियों' के बीच क्या फर्क है? क्यों System.gc () कॉल करने के लिए खराब अभ्यास है?

फ़ंक्शन कॉल परिणाम के शब्दों को परिवर्तित करने वाले पैनेथेसिस

यह एक अन्य प्रश्न में लिखा गया था कि कोष्ठक में PHP फ़ंक्शन कॉल के परिणाम लपेटने से परिणाम को पूरी तरह से पूर्ण रूप से परिवर्तित किया जा सकता है, जैसे कि निम्न कार्य:

<?php error_reporting(E_ALL | E_STRICT); function get_array() { return array(); } function foo() { // return reset(get_array()); // ^ error: "Only variables should be passed by reference" return reset((get_array())); // ^ OK } foo(); 

मैं दस्तावेज़ीकरण में कुछ भी खोजने की कोशिश कर रहा हूं जो स्पष्ट रूप से और स्पष्ट रूप से बताता है कि यहाँ क्या हो रहा है। सी ++ के विपरीत, मुझे PHP व्याकरण और बयान / अभिव्यक्तियों के अपने उपचार के बारे में पर्याप्त जानकारी नहीं है, इसे स्वयं प्राप्त करने के लिए।

क्या इस व्यवहार के बारे में दस्तावेज में छिपा हुआ है? यदि नहीं, तो क्या कोई इसे अनुमान के सहारे बिना समझा सकता है?


अद्यतन करें

मैंने सबसे पहले यह पाया कि ईएनबीएफ़ ने पीएचपी व्याकरण का प्रतिनिधित्व करने की धमकी दी है, और मेरी लिपियों को खुद समझाने की कोशिश की, लेकिन अंततः इसे छोड़ दिया।

उसके बाद, दो foo() संस्करणों की एक .dot फ़ाइल बनाने के लिए phc का उपयोग करके , मैंने निम्न आदेशों का उपयोग करके दोनों स्क्रिप्ट के लिए एएसटी छवियां तैयार की हैं :

 $ yum install phc graphviz $ phc --dump-ast-dot test1.php > test1.dot $ dot -Tpng test1.dot > test1.png $ phc --dump-ast-dot test2.php > test2.dot $ dot -Tpng test2.dot > test2.png 

दोनों ही मामलों में परिणाम बिल्कुल वैसा ही था:

स्निपेट 1 और 2 का पेड़ ट्री

Solutions Collecting From Web of "फ़ंक्शन कॉल परिणाम के शब्दों को परिवर्तित करने वाले पैनेथेसिस"

इस व्यवहार को बग के रूप में वर्गीकृत किया जा सकता है, इसलिए आपको इस पर भरोसा नहीं करना चाहिए।

फ़ंक्शन कॉल पर फेंके जाने वाले संदेश के लिए (सरलीकृत) शर्तों निम्नानुसार हैं (देखें opcode ZEND_SEND_VAR_NO_REF की परिभाषा देखें ZEND_SEND_VAR_NO_REF ):

  • तर्क फ़ंक्शन कॉल नहीं है (या यदि यह है, तो यह संदर्भ द्वारा देता है), और
  • तर्क या तो कोई संदर्भ होता है या इसका संदर्भ गिनती 1 होता है (यदि इसका संदर्भ गिनती 1 है, तो यह संदर्भ में बदल गया है)।

चलिए इनके बारे में अधिक विस्तार से विश्लेषण करें।

पहला बिंदु सही है (फ़ंक्शन कॉल नहीं)

अतिरिक्त कोष्ठकों के कारण, PHP अब पता लगाता है कि तर्क फ़ंक्शन कॉल नहीं है।

एक गैर खाली फ़ंक्शन तर्क सूची पार्स करते समय PHP के लिए तीन संभावनाएं हैं:

  • एक expr_without_variable
  • एक variable
  • (ए & एक variable , संदर्भ सुविधा के द्वारा हटाए गए कॉल-टाइम पास के लिए)

केवल get_array() PHP लिखते समय यह एक variable रूप में देखता है

(get_array()) दूसरी ओर एक variable रूप में योग्य नहीं है। यह एक expr_without_variable

यह अंततः कोड को संकलित करने के तरीके को प्रभावित करता है, अर्थात् SEND_VAR_NO_REF के विस्तारित मान SEND_VAR_NO_REF अब झंडा ZEND_ARG_SEND_FUNCTION शामिल नहीं करेगा, जो कि ZEND_ARG_SEND_FUNCTION कार्यान्वयन में फ़ंक्शन कॉल का पता लगाया जाता है।

दूसरा बिंदु सही है (संदर्भ संख्या 1 है)

कई बिंदुओं पर, ज़ेंड इंजन संदर्भ संदर्भ 1 के साथ गैर-संदर्भ देता है जहां संदर्भ की अपेक्षा की जाती है। ये विवरण उपयोगकर्ता के सामने नहीं होना चाहिए, लेकिन दुर्भाग्य से वे यहां हैं।

आपके उदाहरण में आप एक सरणी लौट रहे हैं जो कि कहीं और से संदर्भित नहीं है यदि यह था, तो आप अभी भी संदेश प्राप्त करेंगे, अर्थात यह दूसरा मुद्दा सही नहीं होगा।

तो निम्न बहुत ही समान उदाहरण काम नहीं करता है :

 <?php $a = array(); function get_array() { return $GLOBALS['a']; } return reset((get_array())); 

ए) यहां क्या हो रहा है यह समझने के लिए, किसी को PHP / मूल्यों / चर और संदर्भों (पीडीएफ, 1.2 एमबी) के हैंडलिंग को समझने की आवश्यकता है। जैसा कि दस्तावेज में कहा गया है : "संदर्भ संकेतक नहीं हैं" ; और आप फ़ंक्शन से संदर्भ द्वारा केवल चर लौटा सकते हैं – और कुछ नहीं।

मेरी राय में, इसका मतलब है कि, PHP में कोई फ़ंक्शन एक संदर्भ वापस करेगा। लेकिन कुछ फ़ंक्शंस (PHP में निर्मित) को तर्क / मान के रूप में मूल्य / चर की आवश्यकता होती है। अब, यदि आप फ़ंक्शन-कॉल की घोंसले के शिकार हैं, तो आंतरिक एक संदर्भ देता है, जबकि बाहरी एक को मान की उम्मीद है। यह 'प्रसिद्ध' E_STRICT- त्रुटि की ओर जाता है "केवल चर संदर्भ के द्वारा पारित किया जाना चाहिए"

 $fileName = 'example.txt'; $fileExtension = array_pop(explode('.', $fileName)); // will result in Error 2048: Only variables should be passed by reference in… 

बी) मुझे प्रश्न में लिंक PHP-syntax विवरण में एक पंक्ति मिली।

 expr_without_variable = "(" expr ")" 

दस्तावेज़ीकरण से इस वाक्य के साथ संयोजन में: "PHP में, जो भी आप लिखते हैं, वह लगभग एक अभिव्यक्ति है। अभिव्यक्ति को परिभाषित करने का सबसे आसान लेकिन सबसे सटीक तरीका 'कुछ भी है जो मान' है।", यह मुझे इस निष्कर्ष पर पहुंचाती है कि यहां तक ​​कि (5) PHP में एक अभिव्यक्ति है, जो मान 5 के साथ एक पूर्णांक का मूल्यांकन करता है।

(जैसा कि $a = 5 केवल एक असाइनमेंट नहीं है बल्कि एक अभिव्यक्ति भी है, जो 5 को समाप्त होता है।)

निष्कर्ष

यदि आप अभिव्यक्ति (...) संदर्भ को पास करते हैं, तो यह अभिव्यक्ति एक मान लौटाएगी, जिसे बाद में बाहरी फ़ंक्शन के तर्क के रूप में पारित किया जा सकता है। अगर (विचार की मेरी लाइन) सच है, तो निम्न दो पंक्तियों को समान रूप से काम करना चाहिए:

 // what I've used over years: (spaces only added for readability) $fileExtension = array_pop( ( explode('.', $fileName) ) ); // vs $fileExtension = array_pop( $tmp = explode('.', $fileName) ); 

PHP 5.0.5 भी देखें : घातक त्रुटि: संदर्भ से केवल चर को पारित किया जा सकता है; 2005/09/13