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(), 기본적으로는 온 (ON) 된 이후 버퍼에 "저장"된 당신이 무엇을 제공하는 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)
Con Antonakos

.ini 파일 순서로 출력 버퍼링을 활성화해야한다고 가정합니다. ob_start();이것이 맞습니까? 활성화되어 있지 않으면 어떻게됩니까?
케빈 휠러

5
@Riley Dutton 당신은 왜 ob_start ()가 사용되는지 말하고 있지 않습니다
Vishnu R Nair

내 코드를 수정 한 후에도 같은 문제가 ob_end_clean있었지만 매력처럼 작동합니다! 감사합니다 @Riley Dutton
Martins

160

나는 이것을 사용하여 PHP를 HTML로 만들 수는 있지만 렌더링 할 수는 없습니다. 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
나는 그렇게 생각하지만 좋은 생각처럼 들리지 않습니다. 별도의 템플릿에서로드하는 것이 좋습니다.
JD Isaacks

1
참고가이 기술을 사용 ob_get_clean()하지 ob_end_clean()
Blazemonger

11
이것을 생각하지 마십시오. 개발하기에 매우 IDE 친화적 인 방법입니다! 게다가, 그것은 성가신 등 내 PHP의 문자열, 지속적으로 탈출 \ "로 자바 스크립트 나 HTML을 내 필요 제거
J-디즐

1
시각적으로 ob_start 사용의 이점을 명확하게 보여줍니다.
klewis

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 함수의 실제 사용법에 대해서도 혼란 스러웠습니다. "리디렉션"동안 사용에 대한 귀하의 답변은 "헤더가 이미 전송되었습니다"라는 오류가 발생한 모든 시간을 상기 시켰습니다. 감사합니다
pat

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과 의미있는 HTML 노드 구조로 결합해야합니다.

이것은 일반적으로 개발자가 JD Isaak이 논의한 것처럼 모든 직접 디스플레이 콘텐츠를 문자열로 감싸서 동적 HTML과 함께 올바르게 전달 / 삽입 할 수 있도록합니다 ... 그것을 감싸고 싶다.

그러나 ob _ ## 메소드를 사용하면 문자열 랩핑 엉망을 피할 수 있습니다. 리터럴 내용은 대신 버퍼로 출력됩니다. 그런 다음 한 번의 간단한 단계로 버퍼의 전체 내용 (모든 리터럴 html)이 dynamic-html 문자열에 연결됩니다.

(내 예제는 리터럴 html이 버퍼에 출력되는 것을 보여줍니다. 그런 다음 html-string에 추가됩니다 ... 또한 string-wrapping-of-html을 보려면 JD Isaaks 예제를 참조하십시오).

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

여기에서 생성 된 출력을 캡처하여 레이아웃에서 완전히 다른 두 곳에 추가 할 수 있습니다.


이런 종류의 내가 찾고있는 것 같습니다. 나는 '섹션'(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.