Php में ob_start () का क्या उपयोग है?


298

के लिए ob_start()उपयोग किया जाता है output bufferingताकि हेडर को बफ़र किया जाए और ब्राउज़र को नहीं भेजा जाए? क्या मैं यहाँ समझ बना रहा हूँ? अगर नहीं तो हमें क्यों इस्तेमाल करना चाहिए ob_start()?

जवाबों:


481

ऐसा ob_start()कहने के बारे में सोचें कि "सब कुछ याद रखना शुरू करें जो सामान्य रूप से आउटपुट होगा, लेकिन अभी तक इसके साथ कुछ भी नहीं करें।"

उदाहरण के लिए:

ob_start();
echo("Hello there!"); //would normally get printed to the screen/output to browser
$output = ob_get_contents();
ob_end_clean();

वहाँ दो अन्य कार्यों आप आमतौर पर के साथ युग्मित कर रहे हैं: ob_get_contents(), जो मूल रूप से आप जो कुछ भी बफर करने के लिए "सुरक्षित" कर दिया गया है के बाद से इसके साथ चालू किया गया था देता है ob_start(), और उसके बाद ob_end_clean()या ob_flush(), जो या तो बचत बातें और छोड देता है जो कुछ भी बचा लिया गया था बंद हो जाता है, या बचत बंद हो जाता है और यह सब एक साथ क्रमशः, आउटपुट करता है।


55
महान व्याख्या। मैं एक कदम आगे जाने के लिए और जगह लेंगे ob_get_contents()साथ ob_get_clean()और हटाने ob_end_clean()के बाद से ob_get_clean()अनिवार्य रूप से दोनों कार्य करता है। संदर्भ: php.net/manual/en/function.ob-get-clean.php (PHP 4> = 4.3.0, PHP 5)
कोन एंटोनकोस

मुझे लगता है कि आउटपुट बफ़रिंग को कॉल करने के लिए .ini फ़ाइल ऑर्डर में सक्षम होना चाहिए ob_start();क्या यह सही है? यदि यह सक्षम नहीं है तो क्या होगा?
केविन व्हीलर

5
@ रिले डटन आप यह नहीं बता रहे हैं कि ob_start () का उपयोग क्यों किया जाता है
विष्णु आर नायर

एक ही मुद्दा था, मेरे कोड को ठीक करने के बाद ob_end_cleanयह एक आकर्षण की तरह काम करता है! धन्यवाद @ रिले डटन
मार्टिंस

160

मैं इसका उपयोग करता हूं इसलिए मैं बहुत सारे HTML के साथ PHP से बाहर निकल सकता हूं, लेकिन इसे प्रस्तुत नहीं कर सकता। यह मुझे एक स्ट्रिंग के रूप में संग्रहीत करने से बचाता है जो IDE रंग-कोडिंग को अक्षम करता है।

<?php
ob_start();
?>
<div>
    <span>text</span>
    <a href="#">link</a>
</div>
<?php
$content = ob_get_clean();
?>

के बजाय:

<?php
$content = '<div>
    <span>text</span>
    <a href="#">link</a>
</div>';
?>

1
क्या यह एक PHP के भीतर कई HTML पेज रखने और उन्हें GET के माध्यम से कॉल करने के तरीके के रूप में इस्तेमाल किया जा सकता है?
joshkrz

1
मुझे लगता है लेकिन यह एक अच्छे विचार की तरह नहीं है। बेहतर होगा कि उन्हें अलग टेम्प्लेट से लोड किया जाए।
जद इसाक्स

1
ध्यान दें कि यह तकनीक उपयोग करती है ob_get_clean(), न कि ob_end_clean()
ब्लेज़ेमॉन्गर

11
इस बारे में कभी नहीं सोचा, यह एक अविश्वसनीय आईडीई-अनुकूल तरीका है! इसके अलावा, यह मेरी PHP में एक स्ट्रिंग के रूप में जावास्क्रिप्ट या HTML होने की मेरी आवश्यकता को दूर करता है, लगातार बच रहा है आदि, जो कि कष्टप्रद है
J-Dizzle

1
आपका दृश्य ob_start का उपयोग करने के लाभों पर एक स्पष्ट तस्वीर देता है।
क्लेविस

86

यहां स्वीकृत उत्तर बताता है कि क्या ob_start()करता है - क्यों नहीं इसका उपयोग किया जाता है (जो सवाल पूछा गया था)।

जैसा कि कहीं और कहा गया है ob_start()कि एक बफर बनाता है जिसे आउटपुट लिखा जाता है।

लेकिन किसी ने यह उल्लेख नहीं किया है कि PHP के भीतर कई बफ़र्स को स्टैक करना संभव है। Ob_get_level () देखें ।

क्यों के रूप में ....

  1. ब्राउज़र को बड़ी मात्रा में HTML भेजने से कम नेटवर्क ओवरहेड से प्रदर्शन लाभ मिलता है।

  2. PHP से डेटा को बड़ी मात्रा में पास करना, आवश्यक संदर्भ स्विच की संख्या को कम करके प्रदर्शन और क्षमता लाभ देता है

  3. Mod_gzip / mod_deflate को डेटा का बड़ा हिस्सा पास करने से प्रदर्शन में लाभ मिलता है कि संपीड़न अधिक कुशल हो सकता है।

  4. आउटपुट बफ़र करने का मतलब है कि आप अभी भी HTTP हेडर को कोड में बाद में हेरफेर कर सकते हैं

  5. स्पष्ट रूप से बफर को फ्लश करने के बाद [हेड] .... [/ हेड] ब्राउजर को एचटीएमएल स्ट्रीम पूरा होने से पहले पेज के लिए अन्य संसाधनों को मार्शमेल करना शुरू कर सकता है।

  6. बफर में आउटपुट कैप्चर करने का मतलब है कि यह ईमेल जैसे अन्य कार्यों को रीडायरेक्ट कर सकता है, या सामग्री के कैश्ड प्रतिनिधित्व के रूप में फाइल में कॉपी किया जा सकता है


29

आपके पास यह पीछे है। ob_start हेडर को बफ़र नहीं करता है, यह सामग्री को बफ़र करता है। उपयोग ob_startकरने से आप सर्वर-साइड बफर में सामग्री को तब तक रख सकते हैं जब तक आप इसे प्रदर्शित करने के लिए तैयार नहीं होते हैं।

इसका उपयोग आमतौर पर इसलिए किया जाता है ताकि पृष्ठ पहले से ही कुछ सामग्री ('भेजा' के बाद 'हेडर' भेज सकें) (अर्थात, पृष्ठ को रेंडर करने के माध्यम से आधे रास्ते पर पुनर्निर्देशित करने का निर्णय लेना)।


3
+1 मैं भी फ़ंक्शन के वास्तविक उपयोग के रूप में भ्रमित था। "पुनर्निर्देशन" के दौरान इसके उपयोग के बारे में आपके उत्तर ने मुझे हर समय याद दिलाया कि मुझे त्रुटि "हेडर पहले से ही भेजा गया है"। धन्यवाद
pat

13

मैं पसंद करता हूं:

ob_start();
echo("Hello there!");
$output = ob_get_clean(); //Get current buffer contents and delete current output buffer

8

यह आगे जेडी इसहाक जवाब स्पष्ट करने के लिए है ...

आपके द्वारा अक्सर चलने वाली समस्या यह है कि आप कई अलग-अलग php स्रोतों से HTML का आउटपुट करने के लिए php का उपयोग कर रहे हैं, और वे स्रोत अक्सर, जो भी कारण से, विभिन्न तरीकों से आउटपुट होते हैं।

कभी-कभी आपके पास शाब्दिक HTML सामग्री होती है जिसे आप सीधे ब्राउज़र में आउटपुट करना चाहते हैं; दूसरी बार आउटपुट गतिशील रूप से बनाया जा रहा है (सर्वर-साइड)।

गतिशील सामग्री हमेशा एक स्ट्रिंग होने जा रही है (?)। अब आपको किसी भी शाब्दिक, डायरेक्ट-टू-डिस्प्ले html ... के साथ इस कठोर डायनेमिक HTML को एक सार्थक HTML नोड संरचना में संयोजित करना है।

यह आमतौर पर डेवलपर को एक स्ट्रिंग में प्रत्यक्ष-से-प्रदर्शन सामग्री को लपेटने के लिए मजबूर करता है (जैसा कि जेडी इसहाक चर्चा कर रहा था) ताकि इसे गतिशील HTML के साथ संयोजन में ठीक से वितरित / सम्मिलित किया जा सके ... हालांकि आप वास्तव में नहीं करते हैं इसे लपेटो चाहते हैं।

लेकिन ob_ ## तरीकों का उपयोग करके आप उस स्ट्रिंग-रैपिंग मेस से बच सकते हैं। इसके बजाय, शाब्दिक सामग्री बफर के लिए आउटपुट है। फिर एक आसान चरण में बफर (आपके सभी शाब्दिक html) की संपूर्ण सामग्री, आपके डायनामिक-html स्ट्रिंग में सम्‍मिलित है।

(मेरे उदाहरण से पता चलता है कि शाब्दिक html बफर के लिए आउटपुट है, जिसे तब html-string में जोड़ा जाता है ... स्ट्रिंग-रैपिंग-ऑफ-html देखने के लिए JD इसहाक उदाहरण भी देखें)।

<?php // parent.php

//---------------------------------
$lvs_html  = "" ;

$lvs_html .= "<div>html</div>" ;
$lvs_html .= gf_component_assembler__without_ob( ) ;
$lvs_html .= "<div>more html</div>" ;

$lvs_html .= "----<br/>" ;

$lvs_html .= "<div>html</div>" ;
$lvs_html .= gf_component_assembler__with_ob( ) ;
$lvs_html .= "<div>more html</div>" ;

echo $lvs_html ;    
//    02 - component contents
//    html
//    01 - component header
//    03 - component footer
//    more html
//    ----
//    html
//    01 - component header
//    02 - component contents
//    03 - component footer
//    more html 

//---------------------------------
function gf_component_assembler__without_ob( ) 
  { 
    $lvs_html  = "<div>01 - component header</div>" ; // <table ><tr>" ;
    include( "component_contents.php" ) ;
    $lvs_html .= "<div>03 - component footer</div>" ; // </tr></table>" ;

    return $lvs_html ;
  } ;

//---------------------------------
function gf_component_assembler__with_ob( ) 
  { 
    $lvs_html  = "<div>01 - component header</div>" ; // <table ><tr>" ;

        ob_start();
        include( "component_contents.php" ) ;
    $lvs_html .= ob_get_clean();

    $lvs_html .= "<div>03 - component footer</div>" ; // </tr></table>" ;

    return $lvs_html ;
  } ;

//---------------------------------
?>

<!-- component_contents.php -->
  <div>
    02 - component contents
  </div>

4

यह फ़ंक्शन केवल हेडर के लिए नहीं है। आप इसके साथ कई दिलचस्प चीजें कर सकते हैं। उदाहरण: आप अपने पृष्ठ को अनुभागों में विभाजित कर सकते हैं और इसका उपयोग इस तरह कर सकते हैं:

$someTemplate->selectSection('header');
echo 'This is the header.';

$someTemplate->selectSection('content');
echo 'This is some content.';

आप यहां उत्पन्न आउटपुट को कैप्चर कर सकते हैं और इसे अपने लेआउट में दो बिल्कुल अलग स्थानों पर जोड़ सकते हैं।


इस तरह का लग रहा है जैसे मैं देख रहा हूं। मुझे 'सेक्शन' (जेएस और सीएसएस फाइलों के बारे में सोचें) के लिए सामान सौंपने की जरूरत है, लेकिन मुझे उन्हें टेम्पलेट के भीतर कॉल करने में सक्षम होने की आवश्यकता है (जो हेडर की तुलना में बाद में लोड हो जाता है) ... तो अगर मैं इसे "$" कहता हूं- > addcss ( 'specificCSStoThisView'); " मैं चाहता हूं कि यह <head> टैग्स के बीच रेंडर करे। मैं यह गूगल करने के लिए प्रतीत नहीं कर सकते, हालांकि। क्या आप मुझे सही दिशा में ले जा सकते हैं? धन्यवाद!
नोबिशप्रो

2

मौजूदा उत्तरों में निम्नलिखित बातों का उल्लेख नहीं किया गया है: बफर आकार विन्यास HTTP हेडर और नेस्टिंग।

Ob_start के लिए बफर आकार विन्यास:

ob_start(null, 4096); // Once the buffer size exceeds 4096 bytes, PHP automatically executes flush, ie. the buffer is emptied and sent out.

उपरोक्त कोड सर्वर के प्रदर्शन में सुधार करता है क्योंकि PHP डेटा का बड़ा हिस्सा भेजेगा, उदाहरण के लिए, 4KB (wihout ob_start कॉल, php ब्राउज़र में प्रत्येक इको भेज देगा)।

यदि आप बिना chunk साइज़ (यानी एक साधारण ob_start ()) के बिना बफर करना शुरू करते हैं, तो पेज को स्क्रिप्ट के अंत में एक बार भेजा जाएगा।

आउटपुट बफ़रिंग HTTP हेडर को प्रभावित नहीं करता है, उन्हें अलग तरीके से संसाधित किया जाता है। हालाँकि, बफरिंग के कारण आप आउटपुट भेजे जाने के बाद भी हेडर भेज सकते हैं, क्योंकि यह अभी भी बफर में है।

ob_start();  // turns on output buffering
$foo->bar();  // all output goes only to buffer
ob_clean();  // delete the contents of the buffer, but remains buffering active
$foo->render(); // output goes to buffer
ob_flush(); // send buffer output
$none = ob_get_contents();  // buffer content is now an empty string
ob_end_clean();  // turn off output buffering

अच्छी तरह से यहाँ समझाया गया: https://phpfashion.com/everything-about-output-buffering-in-php


0

नहीं, आप गलत हैं, लेकिन दिशा फिट है;)

आउटपुट-बफरिंग एक स्क्रिप्ट के आउटपुट को बफ़र करता है। थॉट्स (संक्षेप में) कभी भी echoया उसके बाद print। हेडर के साथ बात यह है, कि वे केवल भेज सकते हैं, अगर वे पहले से ही नहीं भेजे गए हैं। लेकिन HTTP का कहना है, कि हेडर ट्रांसमिशन के पहले हैं। इसलिए यदि आप पहली बार (अनुरोध में) कुछ आउटपुट करते हैं तो हेडर भेजे जाते हैं और आप कोई अन्य हेडर सेट नहीं कर सकते।

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