संदर्भ: PHP के प्रिंट और इको की तुलना करना


182

PHP के बीच क्या अंतर है printऔर echo?

स्टैक ओवरफ्लो में PHP के printऔर echoकीवर्ड के उपयोग के बारे में कई प्रश्न हैं ।

इस पोस्ट का उद्देश्य PHP के संदर्भprint और echoकीवर्ड के बारे में एक कैनोनिकल संदर्भ प्रश्न और उत्तर प्रदान करना और उनके अंतर और उपयोग-मामलों की तुलना करना है।


3
मुझे लगता है कि यहां प्रिंट रिटर्न वैल्यू के बारे में पर्याप्त नहीं है। प्रिंट तेजी से डिबग आउटपुट या इसके जैसे कुछ के लिए उपयोगी है: स्ट्रैप ($ x, $ y)! == FALSE या "कुछ" प्रिंट करें। टाइप करने में तेज और पढ़ने में अच्छा। और "एक फ़ंक्शन प्रिंट है" किसी कारण से पढ़ने के लिए अजीब था (आपका तर्क लगता है ... अजीब और स्पष्ट नहीं है) - यह भाषा का निर्माण है, इससे भी बदतर चीज है जो आप इसके साथ नहीं कर सकते हैं: चर कार्य।
XzKto

1
इसे खुला रखने के लिए यहाँ क्या करना है: 1. एक प्रश्न और उत्तर में विभाजित करें। 2. स्टैक ओवरफ्लो पर विषय वस्तु के बारे में मौजूदा सामग्री का संदर्भ / लिंक (यहां थोड़े पसंद करें: stackoverflow.com/questions/3737139/… ) लेकिन उत्तर में। 3. सीडब्ल्यू होना चाहिए।
केव

"संबंधित कॉलम" ठीक है, लेकिन यह बहुत केंद्रित नहीं है। विहित संदर्भ प्रश्न और उत्तर के रूप में इसके मूल्य को बढ़ाने के लिए इसे अच्छी तरह से शोध किया जाना चाहिए और अन्य विशिष्ट अच्छे उत्तरों के लिंक से मूल्य जुड़ जाएगा।
केव

प्रश्न वास्तव में एक वास्तविक प्रश्न होना चाहिए । एक बार आपके द्वारा किए जाने वाले विहित भाग के संबंध में मैं इसमें एक बैनर जोड़ सकता हूं।
टिम पोस्ट

जवाबों:


185

दो निर्माण क्यों?

प्रिंट और प्रतिध्वनि के बारे में सच्चाई यह है कि जब वे उपयोगकर्ताओं को दो अलग-अलग निर्माणों के रूप में दिखाई देते हैं, तो वे दोनों वास्तव में प्रतिध्वनि के रंग हैं यदि आप मूल बातें करने के लिए नीचे उतरते हैं, अर्थात आंतरिक स्रोत कोड देखें। उस स्रोत कोड में पार्सर के साथ-साथ ओपोड हैंडलर भी शामिल हैं। एक साधारण कार्रवाई पर विचार करें जैसे कि संख्या शून्य प्रदर्शित करना। चाहे आप इको का उपयोग करें या प्रिंट करें, एक ही हैंडलर "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;। (हालांकि, गैर-शब्दार्थ रनटाइम अंतर नीचे ध्यान दें।)

इसलिए हमें केवल शब्दार्थ को परिभाषित करना है printprint e, जब मूल्यांकन किया गया:

  1. इसके एकल तर्क का मूल्यांकन करता है eऔर एक स्ट्रिंग को परिणामी मूल्य टाइप करता है s। (इस प्रकार, print eके बराबर है print (string) e।)
  2. स्ट्रिंग sको आउटपुट बफर में स्ट्रीम करता है (जो अंततः मानक आउटपुट पर स्ट्रीम किया जाएगा)।
  3. पूर्णांक का मूल्यांकन करता है 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


5
मैंने इसे बड़े पैमाने पर संपादित और स्पष्ट किया है, और शब्दार्थ पर एक खंड जोड़ा है। मुझे इस पर पूरा भरोसा है, लेकिन कोई इसे दोबारा जांच सकता है।
jameshfisher

1
क्या इसका मतलब यह है कि, echo $a,$b,$cस्ट्रिंग वेरिएंट के कॉन्सेप्टेशन के लिए उपयोग करना बेहतर है ? मैंने ईमानदारी से इसे उपयोग में नहीं देखा है।
जियोऑफ

1
एक टीएल के बारे में कैसे? डीआर अनुभाग कार्यात्मक अंतर का वर्णन करता है। जैसे: printकेवल एक तर्क देता है, echoकई हो सकते हैं; echoएक अभिव्यक्ति का हिस्सा नहीं हो printसकता है और वापस लौट सकता है ...; और कुछ प्रदर्शन सारांश हो सकते हैं। और उन सभी "क्यों" और "हुड के नीचे" भागों में बाद में
याकॉव

0

मुझे पता है कि मुझे देर हो गई है, लेकिन एक चीज जो मैं जोड़ना चाहूंगा वह मेरे कोड में है

 $stmt = mysqli_stmt_init($connection) or echo "error at init"; 

एक त्रुटि "वाक्यविन्यास त्रुटि, अप्रत्याशित 'प्रतिध्वनि' (T_ECHO) देता है"

जबकि

 $stmt = mysqli_stmt_init($connection) or print "error at init";

ठीक काम करता है।

इको के बारे में डॉक्स कहते हैं "इको (कुछ अन्य भाषा निर्माणों के विपरीत) यहां एक फ़ंक्शन की तरह व्यवहार नहीं करता है" लेकिन प्रिंट डॉक्स के बारे में यह भी कहते हैं कि "प्रिंट वास्तव में एक वास्तविक कार्य नहीं है (यह एक भाषा निर्माण है)" यहां । तो मुझे यकीन नहीं है कि क्यों। और इको और प्रिंट डॉक्स के बारे में भी कहते हैं कि "गूंज के लिए प्रमुख अंतर यह है कि प्रिंट केवल एक तर्क को स्वीकार करता है और हमेशा 1." यहाँ

मुझे खुशी होगी अगर कोई इस व्यवहार के बारे में कुछ प्रकाश डाल सके।

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