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();

通常、ペアにする他の2つの関数があります。はob_get_contents()、基本的にでオンになってからバッファーに「保存」されたものをすべて提供しob_start()、次にまたはは、保存を停止して保存されたものを破棄するob_end_clean()ob_flush()、保存を停止しますそれぞれ同時にすべてを出力します。


55
素晴らしい説明。基本的に両方の機能を実行するので、私はさらに一歩進んで置き換えob_get_contents()ob_get_clean()削除します。参照:php.net/manual/en/function.ob-get-clean.php(PHP 4> = 4.3.0、PHP 5)ob_end_clean()ob_get_clean()
Con Antonakos

呼び出すにob_start();は、.iniファイルの順序で出力バッファリングを有効にする必要があると思います。これは正しいですか。有効になっていない場合はどうなりますか?
Kevin Wheeler

5
@Riley Duttonなぜob_start()が使用されるのか分からない
Vishnu R Nair

同じ問題を抱えていましたが、コードを修正した後ob_end_clean、魅力的に機能しました!ありがとう@Riley Dutton
Martins

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
これを1つのPHP内に複数のhtmlページを作成し、GET経由で呼び出す方法として使用できますか?
joshkrz

1
私はそう思いますが、それは良い考えのようには聞こえません。別々のテンプレートからそれらをロードする方が良いでしょう。
JD Isaacks 2013年

1
この手法ではob_get_clean()、ではなくを 使用していることに注意してくださいob_end_clean()
Blazemonger 2013年

11
これを考えたことはありませんが、これは信じられないほどIDEフレンドリーな開発方法です。さらに、PHPでJavascriptまたは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. [head] .... [/ head]の出力後にバッファを明示的にフラッシュすると、ブラウザはHTMLストリームが完了する前にページの他のリソースのマーシャリングを開始できます。

  6. 出力をバッファにキャプチャすると、メールなどの他の機能にリダイレクトしたり、コンテンツのキャッシュされた表現としてファイルにコピーしたりできます


29

あなたはそれを逆に持っています。ob_startはヘッダーをバッファリングせず、コンテンツをバッファリングします。を使用ob_startすると、コンテンツを表示する準備ができるまで、サーバー側のバッファにコンテンツを保持できます。

これは、ページがヘッダーを送信できるようにするために一般的に使用されます。これは、ページがすでに一部のコンテンツを「送信」した後です(つまり、ページのレンダリングの途中でリダイレクトすることを決定します)。


3
+1私も関数の実際の使い方について混乱しました。「リダイレクト」中の使用に関するあなたの答えは、「ヘッダーはすでに送信されました」というエラーが発生したことを何度も思い出させてくれました。おかげで
パット

13

私は好む:

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

8

これは、JD Isaaksの回答をさらに明確にするためです...

よくある問題は、phpを使用して多くの異なるphpソースからhtmlを出力していることです。これらのソースは、何らかの理由でさまざまな方法で出力されることがよくあります。

ブラウザに直接出力したいリテラルhtmlコンテンツがある場合があります。その他の場合、出力は動的に作成されます(サーバー側)。

動的コンテンツは常に(?)文字列になります。次に、この文字列化された動的htmlを任意のリテラル、直接表示するhtml ...を1つの意味のあるhtmlノード構造に結合する必要があります。

これは通常、開発者にすべての直接表示コンテンツを(JD Isaakが説明したように)文字列にラップすることを強制し、動的HTMLと組み合わせて適切に配信/挿入できるようにします...包んでほしい。

しかし、ob _ ##メソッドを使用することで、その文字列の折り返しの混乱を回避できます。代わりに、リテラルコンテンツはバッファに出力されます。次に、1つの簡単なステップで、バッファーのすべてのコンテンツ(すべてのリテラルhtml)が動的HTMLストリングに連結されます。

(私の例では、リテラルhtmlがバッファーに出力され、それがhtml-stringに追加されています... JD Isaaksの例も見て、string-wrapping-of-htmlを確認してください)。

<?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.';

ここで生成された出力をキャプチャして、レイアウトの2つのまったく異なる場所に追加できます。


この種は私が探しているものに似ています。「セクション」にコンテンツをレンダリングする必要があります(JSおよびCSSファイルを考えてください)が、テンプレート内でそれらを呼び出すことができる必要があります(ヘッダーより後でロードされます)...したがって、「$ this- > addcss( 'specificCSStoThisView'); " <head>タグ間でレンダリングしたい。しかし、私はこれをグーグルすることができないようです。正しい方向に向けてもらえますか?ありがとうございました!
NoobishPro

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などの大きなデータチャンクを送信するため、サーバーのパフォーマンスを向上させます(ob_start呼び出しがない場合、phpは各エコーをブラウザーに送信します)。

チャンクサイズなしでバッファリングを開始すると(つまり、単純な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によると、そのヘッダーは送信の最初のものです。そのため、(リクエストで)初めて何かを出力する場合、ヘッダーが送信され、他のヘッダーを設定することはできません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.