दो निर्माण क्यों?
प्रिंट और प्रतिध्वनि के बारे में सच्चाई यह है कि जब वे उपयोगकर्ताओं को दो अलग-अलग निर्माणों के रूप में दिखाई देते हैं, तो वे दोनों वास्तव में प्रतिध्वनि के रंग हैं यदि आप मूल बातें करने के लिए नीचे उतरते हैं, अर्थात आंतरिक स्रोत कोड देखें। उस स्रोत कोड में पार्सर के साथ-साथ ओपोड हैंडलर भी शामिल हैं। एक साधारण कार्रवाई पर विचार करें जैसे कि संख्या शून्य प्रदर्शित करना। चाहे आप इको का उपयोग करें या प्रिंट करें, एक ही हैंडलर "ZEND_ECHO_SPEC_CONST_HANDLER" को आमंत्रित किया जाएगा। प्रिंट के लिए हैंडलर एक चीज़ करता है इससे पहले कि वह हैंडलर को इको के लिए आमंत्रित करे, यह सुनिश्चित करता है कि प्रिंट के लिए रिटर्न वैल्यू 1 है, जो निम्नानुसार है:
ZVAL_LONG(&EX_T(opline->result.var).tmp_var, 1);
( संदर्भ के लिए यहां देखें )
वापसी मूल्य एक सुविधा है जिसे एक सशर्त अभिव्यक्ति में प्रिंट का उपयोग करना चाहिए। क्यों 1 और 100 नहीं? वैसे PHP में 1 या 100 की सत्यता एक ही है, अर्थात सत्य, जबकि एक बूलियन संदर्भ में 0 एक झूठे मूल्य के रूप में समान है। PHP में सभी गैर-शून्य मान (सकारात्मक और नकारात्मक) सत्य मान हैं और यह PHP के पर्ल विरासत से प्राप्त होता है।
लेकिन, यदि यह मामला है, तो किसी को आश्चर्य हो सकता है कि गूंज कई तर्क लेती है जबकि प्रिंट केवल एक को संभाल सकता है। इस उत्तर के लिए हमें विशेष रूप से फ़ाइल zend_language_parser.y , पार्सर की ओर मुड़ने की आवश्यकता है । आप ध्यान दें कि इको में लचीलापन है, ताकि यह एक या कई भावों को प्रिंट कर सके ( यहाँ देखें )। जबकि प्रिंट केवल एक अभिव्यक्ति को प्रिंट करने के लिए विवश है ( वहां देखें )।
वाक्य - विन्यास
सी प्रोग्रामिंग भाषा और इससे प्रभावित भाषाओं जैसे PHP में, कथनों और अभिव्यक्तियों में अंतर होता है। Syntactically, echo expr, expr, ... expr
एक वक्तव्य है जबकि print expr
एक अभिव्यक्ति है क्योंकि यह एक मूल्य का मूल्यांकन करता है। इसलिए, अन्य कथनों की तरह, echo expr
अपने दम पर खड़ा है और एक अभिव्यक्ति में शामिल करने में असमर्थ है:
5 + echo 6; // syntax error
इसके विपरीत, print expr
अकेले एक बयान दे सकते हैं:
print 5; // valid
या, एक अभिव्यक्ति का हिस्सा बनें:
$x = (5 + print 5); // 5
var_dump( $x ); // 6
किसी को यह सोचने के लिए लुभाया जा सकता है कि print
क्या यह एक गैर-संचालक है, जैसे कि !
या ~
फिर यह एक संचालक नहीं है। क्या !, ~ and print
आम है कि वे सभी PHP में निर्मित कर रहे हैं और प्रत्येक केवल एक तर्क लेता है। आप print
निम्न अजीब लेकिन मान्य कोड बनाने के लिए उपयोग कर सकते हैं :
<?php
print print print print 7; // 7111
पहली नज़र में यह परिणाम अजीब लग सकता है कि अंतिम प्रिंट स्टेटमेंट पहले '7' के अपने ऑपरेंड को प्रिंट करता है । लेकिन, अगर आप गहराई से खुदाई करते हैं और वास्तविक ऑपकोड को देखते हैं तो यह समझ में आता है:
line # * op fetch ext return operands
---------------------------------------------------------------------------------
3 0 > PRINT ~0 7
1 PRINT ~1 ~0
2 PRINT ~2 ~1
3 PRINT ~3 ~2
4 FREE ~3
5 > RETURN 1
जो पहला ओपोड उत्पन्न होता है, वह 'प्रिंट 7' के अनुरूप होता है। '~ 0' एक अस्थायी चर है जिसका मान है 1. वह चर बन जाता है और अगले प्रिंट ओपोड के लिए ऑपरेट होता है जो बदले में एक अस्थायी चर देता है और प्रक्रिया दोहराता है। अंतिम अस्थायी चर का उपयोग बिल्कुल नहीं किया जाता है, यह मुक्त हो जाता है।
print
एक मूल्य क्यों वापस करता है और echo
क्या नहीं?
भाव मूल्यों का मूल्यांकन करते हैं। उदाहरण के लिए 2 + 3
मूल्यांकन करता है 5
, और abs(-10)
मूल्यांकन करता है 10
। चूँकि print expr
यह स्वयं एक अभिव्यक्ति है, तो इसे एक मूल्य रखना चाहिए और यह करता है, 1
एक सत्य परिणाम को इंगित करने का एक सुसंगत मूल्य और एक गैर-शून्य मान वापस करने से यह अभिव्यक्ति दूसरी अभिव्यक्ति में शामिल करने के लिए उपयोगी हो जाती है। इस स्निपेट में उदाहरण के लिए, प्रिंट का रिटर्न मान फ़ंक्शन अनुक्रम निर्धारित करने में उपयोगी है:
<?php
function bar( $baz ) {
// other code
}
function foo() {
return print("In and out ...\n");
}
if ( foo() ) {
bar();
}
जब मक्खी पर डिबगिंग की बात आती है, तो आपको विशेष मूल्य का प्रिंट मिल सकता है, जैसा कि अगले उदाहरण में दिखाया गया है:
<?php
$haystack = 'abcde';
$needle = 'f';
strpos($haystack,$needle) !== FALSE OR print "$needle not in $haystack";
// output: f not in abcde
साइड-नोट के रूप में, आम तौर पर, कथन अभिव्यक्ति नहीं हैं; वे एक मूल्य वापस नहीं करते हैं। अपवाद, निश्चित रूप से अभिव्यक्ति कथन हैं जो एक कथन के रूप में उपयोग किए जाने वाले प्रिंट और यहां तक कि सरल अभिव्यक्तियों का उपयोग करते हैं, जैसे कि 1;
, एक सिंटैक्स जो PHP सी से विरासत में मिला है। अभिव्यक्ति कथन अजीब लग सकता है लेकिन यह बहुत उपयोगी है, जिससे तर्कों को पारित करना संभव हो जाता है कार्य करता है।
है print
एक समारोह?
नहीं, यह एक भाषा निर्माण है। जबकि सभी फ़ंक्शन कॉल अभिव्यक्ति हैं, print (expr)
दृश्य के बावजूद एक अभिव्यक्ति है, जो ऐसा प्रतीत होता है जैसे यह फ़ंक्शन कॉल सिंटैक्स का उपयोग कर रहा था। सच में ये कोष्ठक अभिव्यक्ति के मूल्यांकन के लिए उपयोगी कोष्ठक-एक्सप्र सिंटैक्स हैं। इस तथ्य के लिए जिम्मेदार है कि कई बार वे वैकल्पिक होते हैं यदि अभिव्यक्ति एक सरल है, जैसे कि print "Hello, world!"
। अधिक जटिल अभिव्यक्ति के साथ जैसे print (5 ** 2 + 6/2); // 28
कि कोष्ठक अभिव्यक्ति के मूल्यांकन में सहायता करते हैं। फ़ंक्शन नामों के विपरीत, print
वाक्यात्मक रूप से एक कीवर्ड है , और शब्दार्थ "भाषा निर्माण" है ।
PHP में "भाषा निर्माण" शब्द आमतौर पर "छद्म" कार्यों को संदर्भित करता है जैसे isset
या empty
। यद्यपि ये "निर्माण" बिल्कुल कार्यों की तरह दिखते हैं, वे वास्तव में fexprs हैं , अर्थात् , उनका मूल्यांकन किए बिना तर्क पारित किए जाते हैं, जिन्हें संकलक से विशेष उपचार की आवश्यकता होती है। print
एक ऐसा कार्य होता है जो किसी कार्य के समान ही अपने तर्क का मूल्यांकन करने के लिए चुनता है।
अंतर को मुद्रण द्वारा देखा जा सकता है get_defined_functions()
: कोई print
फ़ंक्शन सूचीबद्ध नहीं है। (हालांकि printf
और दोस्त हैं: विपरीत print
, वे सच्चे कार्य हैं।)
फिर प्रिंट (फू) क्यों काम करता है?
उसी कारण से जो echo(foo)
काम करता है। ये कोष्ठक फ़ंक्शन कॉल कोष्ठक से काफी भिन्न हैं क्योंकि वे इसके बजाय अभिव्यक्तियों से संबंधित हैं। यही कारण है कि एक कोड हो सकता है echo ( 5 + 8 )
और प्रदर्शन ( संदर्भ देखें ) के लिए 13 के परिणाम की उम्मीद कर सकता है । ये कोष्ठक एक कार्य को लागू करने के बजाय एक अभिव्यक्ति का मूल्यांकन करने में शामिल हैं। नोट: PHP में कोष्ठकों के लिए अन्य उपयोग हैं, जैसे कि अगर-सशर्त अभिव्यक्ति, असाइनमेंट सूची, फ़ंक्शन घोषणाएं आदि।
वाक्यविन्यास त्रुटियों में परिणाम print(1,2,3)
और क्यों होता है echo(1,2,3)
?
वाक्यविन्यास है print expr
, echo expr
या echo expr, expr, ..., expr
। जब PHP का सामना होता है (1,2,3)
, तो वह इसे एक एकल अभिव्यक्ति के रूप में पार्स करने की कोशिश करता है और विफल रहता है, क्योंकि सी के विपरीत, पीएचपी में वास्तव में एक बाइनरी कम्यूटर ऑपरेटर नहीं है; अल्पविराम एक विभाजक के रूप में अधिक कार्य करता है। (आप PHP के फॉर-लूप्स में फिर भी एक बाइनरी कॉमा पा सकते हैं, सिंटैक्स इसे सी से विरासत में मिला है)
शब्दार्थ
इस कथन echo e1, e2, ..., eN;
को वाक्यगत शर्करा के रूप में समझा जा सकता है echo e1; echo e2; ...; echo eN;
।
चूंकि सभी भाव बयान कर रहे हैं, और echo e
हमेशा की तरह एक ही साइड इफेक्ट है print e
, और की वापसी मान print e
जब एक बयान के रूप में इस्तेमाल नजरअंदाज कर दिया है, हम समझ सकते हैं echo e
के लिए वाक्यात्मक चीनी के रूप में print e
।
इन दो अवलोकनों का मतलब है कि के echo e1, e2, ..., eN;
लिए कृत्रिम चीनी के रूप में देखा जा सकता है print e1; print e2; ... print eN;
। (हालांकि, गैर-शब्दार्थ रनटाइम अंतर नीचे ध्यान दें।)
इसलिए हमें केवल शब्दार्थ को परिभाषित करना है print
। print e
, जब मूल्यांकन किया गया:
- इसके एकल तर्क का मूल्यांकन करता है
e
और एक स्ट्रिंग को परिणामी मूल्य टाइप करता है s
। (इस प्रकार, print e
के बराबर है print (string) e
।)
- स्ट्रिंग
s
को आउटपुट बफर में स्ट्रीम करता है (जो अंततः मानक आउटपुट पर स्ट्रीम किया जाएगा)।
- पूर्णांक का मूल्यांकन करता है
1
।
बाईटेकोड स्तर पर अंतर
print
रिटर्न वैरिएबल (pseudocode) को आबाद करने का एक छोटा सा ओवरहेड शामिल है
print 125;
PRINT 125,$temp ; print 125 and place 1 in $temp
UNSET $temp ; remove $temp
एक echo
ओपकोड के लिए एकल संकलन:
echo 125;
ECHO 125
बहु-मूल्य echo
कई opcodes को संकलित करता है
echo 123, 456;
ECHO 123
ECHO 456
ध्यान दें कि बहु-मूल्य echo
अपने तर्कों को पूरा नहीं करता है, लेकिन उन्हें एक-एक करके आउटपुट देता है।
संदर्भ: zend_do_print
, zend_do_echo
।
रनटाइम मतभेद
ZEND_PRINT
इस प्रकार लागू किया जाता है (स्यूडोकोड)
PRINT var, result:
result = 1
ECHO var
तो यह मूल रूप 1
से परिणाम चर में डालता है और ZEND_ECHO
हैंडलर को वास्तविक नौकरी सौंपता है। ZEND_ECHO
निम्नलिखित करता है
ECHO var:
if var is object
temp = var->toString()
zend_print_variable(temp)
else
zend_print_variable(var)
जहां zend_print_variable()
वास्तविक "मुद्रण" करता है (वास्तव में, यह केवल एक समर्पित SAPI फ़ंक्शन को पुनर्निर्देशित करता है)।
गति: echo x
बनामprint x
प्रतिध्वनि के विपरीत , प्रिंट एक अस्थायी चर आवंटित करता है। हालांकि, इस गतिविधि पर बिताए समय की मात्रा माइनसक्यूल है, इसलिए इन दो भाषा निर्माणों के बीच का अंतर नगण्य है।
गति: echo a,b,c
बनामecho a.b.c
पहले वाला तीन अलग-अलग कथनों का संकलन करता है। दूसरा संपूर्ण अभिव्यक्ति का मूल्यांकन करता है a.b.c.
, परिणाम को प्रिंट करता है और इसे तुरंत निपटान करता है। चूँकि समासन में मेमोरी एलोकेशन और कॉपी करना शामिल होता है, इसलिए पहला विकल्प अधिक कुशल होगा।
तो कौन सा उपयोग करना है?
वेब अनुप्रयोगों में, आउटपुट ज्यादातर टेम्पलेट्स में केंद्रित होता है। चूंकि टेम्प्लेट उपयोग करते हैं <?=
, जो कि अन्य का नाम है echo
, इसलिए echo
कोड के अन्य भागों में भी छड़ी करना तर्कसंगत लगता है । echo
एक अतिरिक्त लाभ उन्हें अभिव्यक्ति के बिना कई अभिव्यक्ति को मुद्रित करने में सक्षम होने का है और इसमें अस्थायी रिटर्न चर को आबाद करने का ओवरहेड शामिल नहीं है। तो, उपयोग करें echo
।