दिलचस्प पोस्ट
सुपर क्लास से उपवर्ग विधि को कॉल करना मैं TransactionScope का उपयोग सी # में कैसे करूं? आखिरकार ब्लॉक में लौटाए गए वैरिएबल को क्यों बदलता है, वापसी मूल्य नहीं बदलता है? एक अन्य जेएस फ़ाइल में एक जावास्क्रिप्ट समारोह कॉलिंग गिट में लेखक और कमेंटेटर के बीच का अंतर? कैसे जावा से एक्सएमएल सुंदर मुद्रित करने के लिए? पोस्ट इन्वैडेटट () क्या करता है? अनुबंध-प्रथम एसओए: डिजाइनिंग व्यवसाय डोमेन: डब्ल्यूसीएफ सीएसएस एक तत्व है बच्चों की संख्या का पता लगा सकता है? क्या मैं स्क्रॉल वीआईएल को प्रोग्राम में एंड्रॉइड स्क्रॉल कर सकता हूं? कैसे जावास्क्रिप्ट में datetime प्राप्त करने के लिए? एक IOS 7 पारदर्शी UINavigationBar के लिए उज्ज्वल, उज्ज्वल रंग प्राप्त करना रजिस्ट्री को संपादित करने के लिए C ++ का उपयोग करना PHP ओपीकाचे का उपयोग कैसे करें? Numpy arrays और matrices के बीच अंतर क्या हैं? मुझे किसका उपयोग करना चाहिए?

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

यह एक अन्य प्रश्न में लिखा गया था कि कोष्ठक में 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 का पेड़ ट्री

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

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

फ़ंक्शन कॉल पर फेंके जाने वाले संदेश के लिए (सरलीकृत) शर्तों निम्नानुसार हैं (देखें 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