Php ob_start () kullanımı nedir?


298

Is ob_start()için kullanılan output bufferingbaşlıklar tamponlu ve tarayıcıya gönderilen olmayacak şekilde? Burada mantıklı mıyım? Değilse neden kullanmalıyız ob_start()?

Yanıtlar:


481

Düşünün ob_start()şeklindeki "Başlat normalde outputted edilecek olmasına karşın oldukça henüz onunla bir şey yapmayın herşeyi hatırlayarak."

Örneğin:

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

Tipik olarak eşleştirdiğiniz diğer iki işlev daha vardır: ob_get_contents()temel olarak, açıldığından beri arabellekte "kaydedilen" öğeyi size veren ob_start()ve daha sonra ob_end_clean()veya bir ob_flush()şeyleri kaydetmeyi durduran ve kaydedilenleri atamayan veya kaydetmeyi durduran ve hepsini bir kerede çıkarır.


55
Harika bir açıklama. Ben bir adım daha ileri gidip yerini alacak ob_get_contents()olan ob_get_clean()ve kaldırmak ob_end_clean()beri ob_get_clean()esasen iki işlevi yerine getirir. Referans: php.net/manual/en/function.ob-get-clean.php (PHP 4> = 4.3.0, PHP 5)
Con Antonakos

Çıktı arabellekleme çağırmak için .ini dosya sırayla etkinleştirilmesi gerektiğini varsayalım ob_start();Bu doğru mu? Etkinleştirilmezse ne olur?
Kevin Wheeler

5
@Riley Dutton ob_start () işlevinin neden kullanıldığını söylemiyorsunuz
Vishnu R Nair

Aynı sorunu vardı, kodumu düzelttikten sonra ob_end_cleanbir cazibe gibi çalışıyor! Riley Dutton
Martins

160

Ben PHP çok HTML ile kırmak ama bunu render böylece kullanın. Beni IDE renk kodlamasını devre dışı bırakan bir dize olarak saklamamı sağlıyor.

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

Onun yerine:

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

1
Bu, bir PHP içinde birden fazla html sayfasına sahip olmanın ve bunları GET aracılığıyla çağırmanın bir yolu olarak kullanılabilir mi?
joshkrz

1
Sanırım bu iyi bir fikir gibi gelmiyor. Bunları ayrı şablonlardan yüklemek daha iyi olur.
JD Isaacks

1
Bu tekniğin ob_get_clean()değil, kullandığını unutmayın ob_end_clean()
Blazemonger

11
Bunu hiç düşünmedim, bu inanılmaz derecede IDE dostu bir geliştirme yolu! Ayrıca, sürekli olarak can sıkıcı \ "vb, kaçan PHP benim bir dize olarak Javascript veya HTML olması ihtiyacımı kaldırır
J-Dizzle

1
Görseliniz ob_start kullanmanın yararları hakkında net bir resim verir.
klewis

86

Burada kabul edilen cevap neyin ob_start()kullanılacağını açıklamaktadır - neden kullanıldığını değil (sorulan soru buydu).

Başka ob_start()bir yerde belirtildiği gibi çıktı yazılan bir tampon oluşturur.

Ancak hiç kimse PHP içinde birden fazla arabellek biriktirmenin mümkün olduğunu söylemedi. Bkz. Ob_get_level ().

Neden gelince ....

  1. HTML'yi tarayıcıya daha büyük yığınlar halinde göndermek, ağ yükünün azalmasından performans avantajı sağlar.

  2. Verileri PHP'den daha büyük parçalar halinde geçirmek, gereken bağlam anahtarı sayısını azaltarak performans ve kapasite avantajı sağlar

  3. Daha büyük veri parçalarını mod_gzip / mod_deflate'e geçirmek, sıkıştırmanın daha verimli olabilmesi açısından performans avantajı sağlar.

  4. çıkışın arabelleğe alınması, HTTP başlıklarını kodun ilerleyen bölümlerinde değiştirebileceğiniz anlamına gelir

  5. [head] .... [/ head] çıktısını aldıktan sonra arabelleği açıkça temizleme , HTML akışı tamamlanmadan önce tarayıcının sayfa için diğer kaynakları paylaşmaya başlamasına izin verebilir.

  6. Çıktıyı bir arabellekte yakalamak, e-posta gibi diğer işlevlere yönlendirilebileceği veya içeriğin önbelleğe alınmış temsili olarak bir dosyaya kopyalanabileceği anlamına gelir


29

Geriye sahipsin. ob_start üstbilgileri arabelleğe almaz, içeriği arabelleğe alır. Kullanımı ob_start, görüntülemeye hazır olana kadar içeriği sunucu tarafı arabelleğinde tutmanıza olanak tanır.

Bu, sayfaların zaten 'bazı içerikler' gönderdikten 'sonra (yani, bir sayfayı oluşturarak yarıya kadar yönlendirmeye karar verdikten sonra) üstbilgi gönderebilmesi için yaygın olarak kullanılır.


3
+1 Ben de işlevin gerçek kullanımı konusunda kafam karıştı. "Yönlendirme" sırasında kullanımı ile ilgili cevabınız bana "Başlıklar zaten gönderildi" hatasını aldığımı hatırlattı. Teşekkürler
pat

13

Tercih ederim:

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

8

bu JD Isaaks'ın cevabını daha da netleştirmek için ...

Sık karşılaştığınız sorun, birçok farklı php kaynağından html çıktısı için php kullanmanızdır ve bu kaynaklar genellikle, hangi nedenle olursa olsun, farklı yollarla çıktıdır.

Bazen doğrudan tarayıcıya göndermek istediğiniz gerçek html içeriği olabilir; diğer zamanlarda çıktı dinamik olarak oluşturulur (sunucu tarafı).

Dinamik içerik her zaman (?) Bir dize olacaktır. Şimdi bu dize dinamik html herhangi bir gerçek, görüntülemek için doğrudan html ... ile bir anlamlı html düğüm yapısında birleştirmek zorunda.

Bu genellikle geliştiriciyi, doğrudan görüntülenen tüm içeriği bir dizeye (JD Isaak'ın tartıştığı gibi) sarmaya zorlar, böylece dinamik html ile birlikte düzgün bir şekilde teslim edilebilir / eklenebilir ... sarılmasını istiyorum.

Ancak ob _ ## yöntemlerini kullanarak bu dize sarma karmaşasını önleyebilirsiniz. Değişmez içerik bunun yerine arabelleğe çıkarılır. Daha sonra kolay bir adımda tamponun tüm içeriği (tüm gerçek html'niz), dynamic-html dizenize birleştirilir.

(Örneğim, daha sonra bir html dizesine eklenen ara belleğe html çıktısı olduğunu gösterir ... html dizesinin kaydırılmasını görmek için JD Isaaks örneğine de bakın).

<?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

Bu işlev yalnızca başlıklar için değildir. Bununla çok ilginç şeyler yapabilirsiniz. Örnek: Sayfanızı bölümlere ayırabilir ve aşağıdaki gibi kullanabilirsiniz:

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

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

Burada oluşturulan çıktıyı yakalayabilir ve düzeninizdeki tamamen farklı iki yere ekleyebilirsiniz.


Bu tür aradığım şey gibi görünüyor. 'Bölümler' şeyler (JS ve CSS dosyalarını düşünmek) render gerekir, ama (başlık daha sonra yüklenir) şablon içinde onları aramak gerekir ... Yani "$ this- > addcss ( 'specificCSStoThisView');" <head> etiketleri arasında oluşturulmasını istiyorum. Ancak bu google görünmüyor. Belki beni doğru yöne yönlendirebilir misin? Teşekkür ederim!
NoobishPro

2

Varolan yanıtlarda aşağıdaki konular belirtilmez: Arabellek boyutu yapılandırması HTTP Üstbilgisi ve Yerleştirme.

Ob_start için arabellek boyutu yapılandırması:

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

Yukarıdaki kod, PHP'nin daha büyük veri parçaları, örneğin 4KB (ob_start çağrısı olmadan, php her yankı tarayıcıya gönderir) göndereceğinden sunucu performansını artırır.

Parça boyutu (yani basit bir ob_start ()) olmadan arabelleğe almaya başlarsanız, sayfa komut dosyasının sonunda bir kez gönderilir.

Çıktı tamponlaması HTTP üstbilgilerini etkilemez, farklı şekilde işlenir. Ancak, arabellekleme nedeniyle, çıktılar gönderildikten sonra bile üstbilgileri gönderebilirsiniz, çünkü hala arabellekte bulunur.

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

Burada güzel açıkladı: https://phpfashion.com/everything-about-output-buffering-in-php


0

Hayır, yanılıyorsunuz, ama yön uyuyor;)

Çıktı Tamponlama bir komut dosyasının çıktısını arabelleğe alır. Thats (kısaca) sonra her şey echoveya print. Üstbilgileri olan şey, henüz gönderilmedikleri takdirde gönderilebilmeleri. Ancak HTTP, başlıkların ilk iletim olduğunu söylüyor. Dolayısıyla, ilk kez bir şey çıkarırsanız (istekte) üstbilgiler gönderilir ve başka üstbilgiler ayarlayamazsınız.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.