(PHP 4 , PHP 5)

ob_start -- 출력 버퍼링을 켭니다.


설명

bool ob_start ( [callback output_callback])


출력 버퍼링을 켭니다. 출력 버퍼링을 활성화하면, (헤더를 제외한) 스크립트의 모든 출력을 내부 버퍼에 저장하고, 실제로 전송하지 않습니다.


이 내부 버퍼의 내용은 ob_get_contents()를 사용하여 문자열 변수로 복사할 수 있습니다. 내부 버퍼에 저장한 내용을 출력하려면,ob_end_flush()를 사용하십시오. 반대로 ob_end_clean()은 버퍼 내용을 버립니다.


선택적인 output_callback 함수를 지정할 수 있습니다. 이 함수는 문자열을 인자로 받고, 문자열을 반환해야 합니다. 이 함수는ob_end_flush()를 호출하거나, 요청이 끝날 때 출력 버퍼가 브라우저로 전송할 때 호출됩니다. output_callback은 출력 버퍼의 모든 내용을 인자로 받아서 브라우저로 전송할 새 출력 버퍼를 결과로 반환할 것이 기대됩니다. output_callback가 호출할 수 있는 함수가 아니라면, 이 함수는 FALSE를 반환합니다.




참고: PHP 4.0.4에서, ob_gzhandler()가 웹 페이지 압축을 지원하는 웹 브라우저에 gz-인코드 데이터를 전송하기 위한 방법으로 생겼습니다. ob_gzhandler()는 브라우저가 허용하는 내용 인코딩 형태를 확인하고 그에 따라 출력합니다.




참고: PHP 4.3.2 이전에는 실행할 수 없는 output_callback을 지정해도 FALSE를 반환하지 않았습니다.


출력 버퍼는 쌓여질 수 있기에, 다른 ob_start()가 활성화 중이라도 ob_start()를 호출할 수 있습니다. 단지 정확한 횟수의ob_end_flush()를 호출하도록 하십시오. 다중 출력 콜백 함수를 활성화하면, 출력은 감싸진 순서대로 빠져나가면서 변경됩니다.


ob_end_clean()ob_end_flush()ob_clean()ob_flush()ob_start()는 콜백 함수에서 호출할 수 없습니다. 이들을 콜백 함수에서 호출할 시의 행동은 정의되어 있지 않습니다. 버퍼의 내용을 지우려면 콜백 함수에서 ""(빈 문자열)을 반환하십시오.








예 1. 사용자 정의 콜백 함수 예제






<?php

function callback($buffer
)
{
  
// 모든 apples를 oranges로 치환합니다.
  
return (str_replace("apples""oranges"$buffer
));
}

ob_start("callback"
);

?>

<html>
<body>
<p>It's like comparing apples to oranges.
</body>
</html>

<?php

ob_end_flush
();

?>

출력은:





<html>
<body>
<p>It's like comparing oranges to oranges.
</body>
</html>


참고: ob_get_contents()ob_end_flush()ob_end_clean()ob_implicit_flush()ob_gzhandler().





add a note add a note User Contributed Notes
ob_start

simon
25-Jan-2006 01:51 

Found that variables in class instances we're not being set after the call to ob_start(). 
Call ob_start after the variables are set however and it works but that didn't seem to solve the goal of a self contained templating class.
The fix was to assign the class by reference with '&new'
Here is a simplified working example:
<?php
class Buffer 
{
var 
$template ' - template set in class constructor'
;
function 
Buffer
() { 
   
$this->startBuffer
(); 
}
function 
startBuffer
() {
   
ob_start(array(&$this'doFlush'
));
}
function 
doFlush($buffer
) {
   
/* simple string concat to show use of a 
   template string and the buffer output */
   
return $buffer $this->template

}
}
/* template does not get set:
$buffer1 = new Buffer();
$buffer1->template = ' - template set in instance';
echo 'some buffer content';
*/
/* this works as expected */
$buffer2 = &new Buffer
();
$buffer2->template ' - template set in instance'
;
echo 
'some buffer content';

ernest at vogelsinger dot at
09-Jan-2006 02:57 

When you rely on URL rewriting to pass the PHP session ID you should be careful with ob_get_contents(), as this might disable URL rewriting completely.

Example:
ob_start();
session_start();
echo '<a href=".">self link</a>';
$data = ob_get_contents();
ob_end_clean();
echo $data;

In the example above, URL rewriting will never occur. In fact, rewriting would occur if you ended the buffering envelope using ob_end_flush(). It seems to me that rewriting occurs in the very same buffering envelope where the session gets started, not at the final output stage.

If you need a scenario like the one above, using an "inner envelope" will help:

ob_start();
ob_start();  // add the inner buffering envelope
session_start();
echo '<a href=".">self link</a>';
ob_end_flush(); // closing the inner envelope will activate URL rewriting
$data = ob_get_contents();
ob_end_clean();
echo $data;

In case you're interested or believe like me that this is rather a design flaw instead of a feature, please visit bug #35933 (
http://bugs.php.net/bug.php?id=35933) and comment on it.

cyrille.berliat[no spam]free.fr
17-Oct-2005 07:07 

If you're trying to use ob_start() in some PHP5 classes (probably works on PHP4 classes), this is the good way :

<?

class 
HTMLPage
{
//----------------------------------------------------------------- PUBLIC

//----------------------------------------------------- M鴨odes publiques
   
   
public static function ConvertIntoSGML$source 
)
   
// Mode d'emploi :
   //convertit une string en une SGML valide
   //
   // Renvoie :
   //la chaine trait?br />    //
   // Algorithme :
   //analyse char par char de la chaine. Si un caract? est de nombre ASCII > 127,
   //conversion en son code SGML.
   
{
       
$newString ''
;
       
       for( 
$i 0$i strlen$source ) ; $i
++ ) {
           
$o ord$source$i 
} );
           
           
$newString .= ( ( $o 127 ) ? '&#'.$o.';'$source$i 
} );
       }
       
       return 
$newString
;
   }
   
   
public function FlushSite$source 
)
   {
       return 
$this->ConvertIntoSGML $source 
);
   }
   
//-------------------------------------------- Constructeurs - destructeur
   
function __construct
()
   
// Mode d'emploi (constructeur) :
   //initialise la buffurisation
   //
   // Contrat :
   //
   
{
       
ob_start( array (  & $this 'FlushSite' 
) );
   } 
//---- Fin du constructeur
   
//------------------------------------------------------ M鴨odes Magiques

//------------------------------------------------------------------ PRIVE 

}

// Example :

$webdesign = new HTMLPage 
( );

echo 
'H?o world'
// Will produce the source 'h&#233;llo world'

?>

Without the & before $this, you'll loose your content because ob_start() will call the flushsite() function from a clone of the object and not the caller object himself.

Note : call_back function must be public because ob_start() is in an extern scope from your class :)

I hope this will help you!

php at bucksvsbytes dot com
16-Sep-2005 02:29 

The following should be added: "If outbut buffering is still active when the script ends, PHP outputs it automatically. In effect, every script ends with ob_end_flush()."

admin at bobfrank dot org
29-Aug-2005 12:50 

If you want to run code in the middle of a string that you made, but you want to wait the printing...
(so if you want to allow php in bb-code style, and you want to execute it in order, and print everything in order...)

phpRun($code) {
   ob_start();
   exec($code);
   $output = ob_get_contents();
   ob_end_clean();
   return $output;
}

$str = str_replace("]n", "]", $str);
$match = array('#[php](.*?)[/php]#se');
$replace = array( phpRun( stripslashes('$1') ) );
$str= preg_replace($match, $replace, $str);

echo $str;

kasper at johansen dot tdcadsl dot dk
28-Aug-2005 11:29 

Another way to make your code harder to copy, is to remove all line-breaks and tabs you have in it.

You can use this function to remove those.

You can choose to place "ob_start();" at the start of your main PHP-file, and "ob_end_clean();" at the end of it.

This is not the best solution though. If you are running Apache you might want to do something like this to a ".htaccess"-file:

php_value auto_prepend_file "/home/www/load_before.php"
php_value auto_append_file "/home/www/load_after.php"

(you should replace those files with files that actually exists).

In the "load_before.php" you can place the "ob_start();", and in the "load_after.php" you can do something like this:

<?
   $html 
strtr(ob_get_contents(), array("t" => """n" => """r" => ""
));
   
ob_end_clean
();
   
   echo 
$html
;
?>

This will clean your HTML of all kind of linebreaks (both n and r) and tabulators (t). This will save your users some bandwidth, but it will also make your HTML, JavaScripts and more very difficult to read or copy. That way, making it harder for people to steal your code if you do not want them to.

This isnt in the spirit of OpenSource, but anyway you should be aware that this is possible.

Be aware that if you use PHP-files, to simulate pictures, all linebreaks will also be remove, making them corrupt. A solution to this, could be to check the headers (Content-Type), and if isnt set, or it is "text/html", you can go ahead and remove the linebreaks and tabs.

At my site, with more than 50.000 pictures and about 60 people online, I couldnt see any difference in the loadtime.

But still be aware, that your output will not be sent, before the script is finished, which will make your page slower to load that way also, since it cannot send any output while loading, but will have to wait until the load is finished.

geoffrey at nevra dot net
10-Aug-2005 04:05 

When using a callback with ob_start(), functions like ob_get_contents() don't make use of it, use ob_end_flush() instead.

nb: not tested with every ob_* functions, just ob_get_contents() and ob_end_flush()

05-Aug-2005 11:54 

I usually create my pages in four parts - variable initialisation, import header (using the variables just declared to configure), main body (mostly non-PHP), import footer.  I wondered about making the main body examinable by another PHP script if the main page was included into it.  I found I could control output of the main body by ending the header with an unclosed function which finishes at the start of the footer, thus enclosing the main body.  Output buffering can then be used to read this into a variable.  As a demonstration of how this can be used to control the order of output look at this example:

<?php
$output 
""
;

// Callback to process buffered output
function capture($buffer
)
   {
   
$GLOBALS['output'] .= $buffer
;
   return 
"C "
;
   }

// Calls the printE() function with output capture
function captureE
()
   {
   
ob_start("capture"
);
   
printE
();
   
ob_end_flush
();
   }
?>

A
<?php
// Output 'E' (the main body in the example scenario)
function printE
()
   { 
// (End header after this line) 
?>
E
   <?php 
// (Start footer with this line)
   
}
?>
B
<?php captureE(); 
?>
D
<?php print $output
?>
F
<?php printE(); 
?>
G

The output is A B C D E F E G.

For the application I mentioned above there are two points to note:
 - The page when executed alone must output its main body but the inspection script should suppress this, perhaps by means of a variable set before the page is included and then checked for in the footer output lines.
 - Because the main body is now inside a function it has a different namespace, thus changes may be required to prevent code breaking (e.g. use of globals, handling of functions defined within the main body).

oersoep at gmail dot com
08-Jul-2005 09:46 

These are handy. First one has been mentioned before.

ob_start( array( 'lib_class', 'parse_output' ) );
ob_start( array( $this, 'parse_output' ) );

Note: $this is NOT a reference. Anything the callback saves or logs disappears in the clone ob_start works with. 
It does enable the callback to work with the attributes of $this, like $this->ar_tpl_value or whatever your style is.

The manual says:
"If the optional parameter chunk_size is passed, the callback function is called on every first newline after chunk_size bytes of output. The output_callback parameter may be bypassed by passing a NULL value."
This doesn't work with my 4.3.11. Might be the Zend optimizer though. Daren't turn it off to go see.

Aleksey
25-May-2005 04:08 

This function dynamically changes title of HTML page:

  function change_title($new_title) {
   $output = ob_get_contents();
   ob_end_clean();

   $output = preg_replace("/<title>(.*?)</title>/", "<title>$new_title</title>", $output);
   echo $output;
  }

Example:
  ob_start();
  // ... some output
  change_title('NEW TITLE!');

jds1509 at NOSPAMrit dot edu
24-May-2005 11:06 

This code demonstrates the affect of providing a value to the chunk_size parameter. A value of 1 or 0 will be ignored by php. Here's the Code:

<?

function callback($buffer
)
{
   return 
"TRAPPED:".$buffer."<br/>"
;
}

ob_start("callback",2
);

echo 
"long string, so callback"
;
echo 
"X"
;
echo 
" - no callback, less than 2 chars"
;

?>newlines,
but
no
callback
!
<?

// PHP block

?>PHP block initiates callback.
<?

echo "One more callback at EOF..."
;

?>

The code above outputs:

TRAPPED:long string, so callback
TRAPPED:X - no callback, less than 2 chars
TRAPPED:newlines, but no callback !
TRAPPED:PHP block initiates callback.
TRAPPED:One more callback at EOF...
TRAPPED:

rafa dot chacon at factorydea dot com
10-May-2005 06:10 

If you're trying to include a php file inside a loop by require_once (in example, a dinamic email template) and change the value of some variables (in example, url to unsuscribe, different for each user), you should use

<?php

// ... some code

$usermail = array("email1""email2"
, ...);

for(
$i 0$i $MAX$i
++)
{
       
$usermail_unsuscribe $usermail[$i
];
       
ob_start
();
       include(
"email_template.php"
);
       
ob_clean
();
}
?>

Otherwise $usermail_unsuscribe will get only "email1" value.

JM
09-May-2005 04:17 

I don't claim to understand this--I would have expected the exact opposite--but it seems that 
  ob_start() ... ob_end_flush()
can massively improve perfomance, by at least a factor of 10 (admittedly a small number of samples).

I tried this after discovering that I could move a large (100ms) bottleneck in one of my scripts into
   echo "<!-- about 40 characters of junk -->";
which clearly shouldn't have taken long to run.

My unfounded theory is that without buffering, the interaction between PHP4.3.4 and Apache is not optimized, whereas with buffering, PHP delivers the entire page at once, which Apache handles better.

I should add that this is under https.

Ray Paseur (Paseur ... ImagineDB.com)
02-Mar-2005 06:50 

You can use PHP to generate a static HTML page.  Useful if you have a complex script that, for performance reasons, you do not want site visitors to run repeatedly on demand.  A "cron" job can execute the PHP script to create the HTML page.  For example:

<?php 
// CREATE index.html
   
ob_start
();
/* PERFORM COMLEX QUERY, ECHO RESULTS, ETC. */
   
$page ob_get_contents
();
   
ob_end_clean
();
   
$cwd getcwd
();
   
$file "$cwd" .'/'"index.html"
;
   @
chmod($file,0755
);
   
$fw fopen($file"w"
);
   
fputs($fw,$pagestrlen($page
));
   
fclose($fw
);
   die();
?>

eddie
14-Feb-2005 01:09 

I use this function for deleting not needed characters within the html code before sending the whole stuff to the browser.

function callback($buffer){
   $buffer = str_replace("n", "", $buffer);
   $buffer = str_replace("t", "", $buffer);
   $buffer = str_replace(chr(13), "", $buffer);
   $buffer = ereg_replace("<!-- [/ a-zA-Z]* -->", "", $buffer);
   return $buffer;
}

First str_replace will delete any newlines, second any tabs and the third any carriage return. Finally the regular expression will delete any html-comment which consists of /, space, a-z or A-Z.
Using this saves about 1kb on every pageload.

FB
02-Feb-2005 11:59 

I've noticed a bug with MSIE for non cached contents if your page is less than 4096 octets : you have to refresh the page each time to view its content !

Here is the solution to prevent this stupid behaviour of MSIE : just insert this code at the top of your scripts :

function ob_callback($buffer)
{
   return $buffer . str_repeat(' ', max(0, 4097 - strlen($buffer)));
}

ob_start('ob_callback');

d_spagnoli at yahoo dot it
28-Dec-2004 11:39 

nl2br() is not a callable function, to make it work define a new one like this:

function mynl2br($str){
   return nl2br($str);
}

example:

ob_start("nl2br");
echo "under pressurenpushing down on me";
$str_error=ob_get_flush();

doesn't work, use ob_start("mynl2br") instead.

PHP 4.3.9

aaron at offtone.com
14-Nov-2004 10:19 

My callback is stored in a function class, and using ob_start ('Class::callback') wasn't working. Not wanting to instantiate the class (no need, it's a function class) I tried this and it worked a charm:

ob_start (array (Class, 'callback'));

PHP 4.3.4

dev at kiwicore dot org
29-Oct-2004 05:49 

I wanted to do things a very particular way with output buffering and shutdown functions; using register_shutdown_function instead of the built in callback feature of this function. However, one should note that this won't work, because the contents of the buffer are no longer in scope when PHP is calling the shutdown functions. This would have been easy to see EXCEPT that PHP graciously flushes any unsent buffers at the end of the script, or when calling exit. So:

<?php
   ob_start
();
   echo 
'hi'
;
   exit;
?>

Prints "hi". In a nutshell, if you want it to have a shutdown function that handles an output buffer, just specify it in ob_start() and let PHP automatically call it at the end of the script.

jkloss at hotmail dot com
18-Mar-2004 12:20 

If ob_start does not seem to be working for you, note that with Apache 2 the flush() function causes PHP to send headers regardless of whether ob_start had been called before flush.

ob_start();
echo 'test';
flush();

will cause Apache 2 to send whatever headers may be stacked up - which means you can't use a header(location:xxx) after the flush.  To fix, remove the flush().  Spent several hours discovering this.  Apache 1.x didn't work this way.

mjr
11-Mar-2004 02:10 

If you're using object-orientated code in PHP you may, like me, want to use a call-back function that is inside an object (i.e. a class function). In this case you send ob_start a two-element array as its single argument. The first element is the name of the object (without the $ at the start), and the second is the function to call. So to use a function 'indent' in an object called '$template' you would use <?php ob_start(array('template''indent')); ?>.

zeisss at web dot de
24-Nov-2003 02:03 

Note that the current working directory changes in the callback procedure (Changed from htdocs to windowssystem32 on my system).

You have to use absolut paths if you want to open files on your local system.

ed.oohay (a) suamhcs_rodnan
22-Nov-2003 10:18 

Output Buffering even works in nested scopes or might be applied in recursive structures... thought this might save someone a little time guessing and testing :)

<pre>
<?php
   
   ob_start
();              
// start output buffer 1
   
echo "a";                
// fill ob1
       
       
ob_start();              
// start output buffer 2
       
echo "b";                
// fill ob2
       
$s1 ob_get_contents(); 
// read ob2 ("b")
       
ob_end_flush();          
// flush ob2 to ob1
       
   
echo "c";                
// continue filling ob1
   
$s2 ob_get_contents(); 
// read ob1 ("a" . "b" . "c")
   
ob_end_flush();          
// flush ob1 to browser
   
   // echoes "b" followed by "abc", as supposed to:
   
echo "<HR>$s1<HR>$s2<HR>"
;
   
?></pre>

'php' 카테고리의 다른 글

projects snoopy  (0) 2012.03.09
array_merge  (0) 2012.02.15
피카사 웹 앨범으로 PHP 응용 프로그램 개발하기  (0) 2011.12.28
PHP대용량 파일 업로드시 확인해야될 문제  (0) 2011.12.13
Migrating from PHP 5.2.x to PHP 5.3.x  (0) 2011.12.08

+ Recent posts