ob_start

Description

This function will turn output buffering on. While output buffering is
active no output is sent from the script (other than headers), instead the
output is stored in an internal buffer.

The contents of this internal buffer may be copied into a string variable
using ob_get_contents(). To output what is stored in
the internal buffer, use ob_end_flush(). Alternatively,
ob_end_clean() will silently discard the buffer
contents.

Warning

Some web servers (e.g. Apache) change the working directory of a script
when calling the callback function. You can change it back by e.g.
chdir(dirname($_SERVER['SCRIPT_FILENAME'])) in the
callback function.

Output buffers are stackable, that is, you may call
ob_start() while another
ob_start() is active. Just make
sure that you call ob_end_flush()
the appropriate number of times. If multiple output callback
functions are active, output is being filtered sequentially
through each of them in nesting order.

Parameters

output_callback

An optional output_callback function may be
specified. This function takes a string as a parameter and should
return a string. The function will be called when
the output buffer is flushed (sent) or cleaned (with
ob_flush(), ob_clean() or similar
function) or when the output buffer
is flushed to the browser at the end of the request. When
output_callback is called, it will receive the
contents of the output buffer as its parameter and is expected to
return a new output buffer as a result, which will be sent to the
browser. If the output_callback is not a
callable function, this function will return FALSE.
This is the callback signature:

stringhandler
( string$buffer
[, int$phase
] )

buffer

Contents of the output buffer.

phase

Bitmask of PHP_OUTPUT_HANDLER_* constants.

If output_callback returns FALSE original
input is sent to the browser.

The output_callback parameter may be bypassed
by passing a NULL value.

ob_end_clean(), ob_end_flush(),
ob_clean(), ob_flush() and
ob_start() may not be called from a callback
function. If you call them from callback function, the behavior is
undefined. If you would like to delete the contents of a buffer,
return "" (a null string) from callback function.
You can't even call functions using the output buffering functions like
print_r($expression, true) or
highlight_file($filename, true) from a callback
function.

Note:

ob_gzhandler() function exists to
facilitate sending gz-encoded data to web browsers that support
compressed web pages. ob_gzhandler() determines
what type of content encoding the browser will accept and will return
its output accordingly.

chunk_size

If the optional parameter chunk_size is passed, the
buffer will be flushed after any output call which causes the buffer's
length to equal or exceed chunk_size. The default
value 0 means that the output function will only be
called when the output buffer is closed.

Prior to PHP 5.4.0, the value 1 was a special case
value that set the chunk size to 4096 bytes.

flags

The flags parameter is a bitmask that controls
the operations that can be performed on the output buffer. The default
is to allow output buffers to be cleaned, flushed and removed, which
can be set explicitly via
PHP_OUTPUT_HANDLER_CLEANABLE |
PHP_OUTPUT_HANDLER_FLUSHABLE |
PHP_OUTPUT_HANDLER_REMOVABLE, or
PHP_OUTPUT_HANDLER_STDFLAGS as shorthand.

Return Values

Changelog

In case ob_start() is used inside an output buffer
callback, this function will no longer issue an E_ERROR
but instead an E_RECOVERABLE_ERROR, allowing custom
error handlers to catch such errors.

5.4.0

The third parameter of ob_start() changed from a
boolean parameter called erase
(which, if set to FALSE, would prevent the output buffer from being
deleted until the script finished executing) to an
integer parameter called flags.
Unfortunately, this results in an API compatibility break for code
written prior to PHP 5.4.0 that uses the third parameter. See
the flags example
for an example of how to handle this with code that needs to be
compatible with both.

5.4.0

A chunk size of 1 now results in chunks of 1 byte
being sent to the output buffer.

4.3.2

This function was changed to return FALSE in case the passed
output_callback can not be executed.

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:

IE 55. sp2 and IE6 as on the date of adding this note have problems with content type gzip and caching http headers. The pages are never cached. I think this combination of http headers can also crash the browser.

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

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:

Some web hosting servers (mine do, at least) have in their php.ini the following setting:output_handler = ob_gzhandler

This proved problematic for php-scripts which returns an image or a binary file in general, since there is no way to determine the content length of the compressed file.

Since I spent a lot of time scouring the net searching for a work-around (.htaccess-modifications were out of the picture for various reasons), I found this to work nicely to cancel out the ob_gzhandler specified in the php.ini:

When a script ends, all buffered output is flushed (this is not a bug: http://bugs.php.net/bug.php?id=42334&thanks=4). What happens when the script throws an error (and thus ends) in the middle of an output buffer? The script spits out everything in the buffer before printing the error!

Here is the simplest solution I have been able to find. Put it at the beginning of the error handling function to clear all buffered data and print only the error:

will put the image bytes into $pngString, and set the content type to image/png. Though the image will not be sent to the client, the png header is still in place; if you do html output here, the browser will most likely display "image error, cannot be viewed", at least firefox does.

You need to set the correct image type (text/html) manually in this case.

I think it's worth noting that while you can't call any output functions such as echo or print from within a callback function, you can still send headers (presumably including cookies, haven't checked). Of course this only works in the first callback, like so:

Not the most inspiring example, but in this case the code is able to sneak a last-minute header in before the headers part of the response is sent. This can be handy if you want to avoid replacing header values that are uncertain.

For example if your code may return an image, but you don't want to set content type until you're sure that the image can be sent successfully, you can use the callback to leave the decision right until the very last moment, by which point you're hopefully sure of what's being sent in the HTTP body.

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.

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.

When a fatal error is thrown, PHP will output the current buffer of Output-Control without postprocessing before printing the error message. If you are working with several output control levels, this might not result in the desired behavior.

You can use an output callback handler to handle this and discard the output.

Therefore, use ob_start("ob_error_handler") in connection with the following:

In extension to the compress() function posted below, here's a nifty little class that improves the idea a bit. Basically, running that compress() function for all your CSS for every single page load is clearly far less than optimal, especially since the styles will change only infrequently at the very worst.

With this class you can simply specify an array of your CSS file names and call dump_style(). The contents of each file are saved in compress()'d form in a cache file that is only recreated when the corresponding source CSS changes.

It's intended for PHP5, but will work identically if you just un-OOP everything and possibly define file_put_contents.

Way to make all stdout and stderr write to a logfrom *inside* a php script.You simply need to make sure to call elog() everyonce in awhile to get output.It's a nice way to "daemonize" a script w.r.t. its logging.

// This allows us to capture all stdout and stderr (and error_log() calls)// to this logfile...// The "collected output" will be flushed anytime "elog()" is used...ini_set("error_log", "/var/log/script.log");ob_start();

function elog($str){ // get anything written to stdout or stderr that did *NOT* use elog() // and write it now... $writeme = ob_get_contents(); if ($writeme) { error_log($writeme); ob_end_clean(); ob_start(); } // now write message this method was called with error_log($str);}

Hi, I use those functions for stripping unnecessary chars in my output code...because I have JavaScript placed in outpout code so I don't remove \n\r\t but just replace them with single space (it could cause errors in scripts)Function stripBufferSkipTextareaTags skips tags Textarea. It's needed to don't loose \n\r when user edit some content...

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...)

Here's a nifty function I use daily. Essentially: include a PHP file - but render its output to a variable, rather than to the buffer. It's also set up to load the script with a variable set, and automagically loads globals into the script's namespace, making it an effective templating scheme. It also has error handling, so that you're not flying blind when using output buffering.

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.

In case of an error the contents of the output buffer are shown along with the error message. If it is really important that this does never happen, you can do the following (but this also eats up the error message):

Note that I could verify that ob_start() and ob_start(null,0) are not always equivalent.

It seems that with ob_start() the output buffer is open with current default parameters of your configuration if they have been explicitly defined.

So, if you have set $chunk_size to any value previously and send data larger than $chunk_size the data will be automatically flushed by blocks of $chunk_size.

If you explicitely define $chunk_size=0, later, when you will use any function as $my_ob_dataoutput=ob_get_clean(); you will get back the whole content of your output (quite unlimited with $chunk_size=0).

I discover this because my var $my_ob_dataoutput was truncated. Using "ob_get_status (true)" function, I could verify that an error (in a lower level or by default out of my control) was setting previously the $chunk_size of ob at 4096.I changed "ob_start()" for "ob_start(null,0)" and everything became OK.

I assume you all know how to build compression classes and use them in your programs, but none has yet to offer the speed and robustness of a binary-compiled module. Furthermore, such modules also log the "compressable" hit in the web log file, thus allowing your favorite web anaysing program to show you reports of bandwidth saved.

Having said that, you might consider the following two modules for Apache:

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:<?phpclass 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';

With ob callback: note that the second parameter sent to your method won't help you differentiate between flush calls and calls to ob_clean, but the buffer contents is sent in both cases, so you end up parsing data that isn't going to be used. Also, note that the constant PHP_OUTPUT_HANDLER_START is never actually sent, rather the integer "3" turns up on first flush:<?php

I suppose the START flag problem *may* be a bug but I'm not able to upgrade before reporting since I must have the same version as my server (I'm on PHP 5.2.6). If anyone has 5.2.11 or other stable version feel free to test/report as you see fit.

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:

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).

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.

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

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:

There is a difference between the documentation and real callback functions invocation.Manual says: "The function will be called when ob_end_flush() is called, or when the output buffer is flushed to the browser at the end of the request."

Actually, the callback function, once set by ob_start(), will be called regardless.Here are the functions that invoke callback function immediately:ob_cleanob_end_cleanob_end_flushob_flushob_get_clean

BUT only two of them return the result returned by the callback (ob_end_flush, ob_flush), other functions discard it.

At the end of the request, even if none of the functions listed above is called, the callback will be called anyway, and its result will be returned to the browser (well, at least this is corresponding to the manual).

There is one more trick:If you set callback function with chunk_size > 1, callback function will be called each time output buffer is equal or exceeds chunk_size and its result will be output to the browser, even if you call any of ob_clean(), ob_end_clean(), ob_get_clean() later, so be aware of this fact.

In regards to below. The best thing to do is create an error handler that catches all non-fatal errors prior and during your ob_start.

works for me all the time. and if there is an error you can format the errors in that script it executed in. From my experience i'm quite sure that would be the most logical choice. wouldn't it? Plus your using objects...Please do think before you can code.

Under certain freak conditions, when an error ocours perfoming an action on an object that cannot be done (either because the object does not exist or the method does not exist) inside of an ob_start() the script will exit and print everything the current function generates before the error, but nothing else, including no error message.

I am at a loss to why no error message appears and am trying to get a working example for the developers that is simpler than my whole program!

So if you are using ob_start() and you get no output, check your objects.... you have made a mistake on them somewhere. The only trouble is you will not know where as there is no error!!

Just for simplicity's sake (and because I had to rewrite it for use at http://www.VideoSift.com anyway), here's a very simplified, pre-PHP5 version. Just add one call to dump_css_cache() for each of your CSS files.

ob_start() opens a buffer in which all output is stored. So every time you do an echo, the output of that is added to the buffer. When the script finishes running, or you call ob_flush(), that stored output is sent to the browser (and gzipped first if you use ob_gzhandler, which means it downloads faster).

The most common reason to use ob_start is as a way to collect data that would otherwise be sent to the browser.

These are two usages of ob_start():

1-Well, you have more control over the output. Trivial example: say you want to show the user an error message, but the script has already sent some HTML to the browser. It'll look ugly, with a half-rendered page and then an error message. Using the output buffering functions, you can simply delete the buffer and sebuffer and send only the error message, which means it looks all nice and neat buffer and send 2-The reason output buffering was invented was to create a seamless transfer, from: php engine -> apache -> operating system -> web user

If you make sure each of those use the same buffer size, the system will use less writes, use less system resources and be able to handle more traffic.

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.

Function ob_start can capture all normal output, assuming no errors occur. Naturally, the programmer will want to know whether errors can also be caught (that is, captured and logged). The answer is that warnings can be caught along with normal output, but that fatal errors and exceptions break the normal buffering and can only be caught separately. Finally, parsing errors cannot be caught at all, because parsing is done in a first pass before execution begins. Of course, even parsing errors can be caught by running PHP in a separate process and capturing the output of that process.

Here is an example that illustrates all these additional details (see also the comment by Philip at set_error_handler function). Those errors that break buffering can be illustrated by uncommenting their lines.

It's easy to add a function that caches the whole page you're going to generate so resources are saved. I wrote it in a file called "cacheable.php", and I included in each file that I want to be cached. It cannot manage files with ob_start inside.

//note you must use register_shutdown_function instead of using "cacheOutputtoFile" as parameter of ob_start as socket is already closed when callback function is called, then the client not get the echo $webpage output.
?>

I'm sure some of you more brilliant minds could pare this down some more, but using the method found at fiftyfoureleven.com for compressing, I got my 10090-byte stylesheet down to 3536 bytes and then again down to 2713 bytes, by stripping unecessary characters from the stylesheet. 2 ob_start calls and the CSS file is now 73% smaller. YMMV.

PHP Suggests: Some web servers (e.g. Apache) change the working directory of a script when calling the callback function. You can change it back by doing, for example, the following in the callback function: chdir(dirname($_SERVER['SCRIPT_FILENAME']))

The solution provided by PHP, does not function as intended when running PHP as a CGI (on CGI mode (CGI-BUILD (--enable-cgi) and/or CLI)). In such a case, PHP is executed as a CGI-BIN and the web server daemon (e.g. Apache) sees SCRIPT_FILENAME as being the PHPCGI processor, and won't look deeper to find what file the PHPCGI processor is actually running/parsing; therefore the path returned by SCRIPT_FILENAME is wrong (most of the time, containing/ending with "cgi-system/php.cgi").

As SCRIPT_FILENAME is the safest way to proceed, but turns to be wrong in this exact situation; PATH_TRANSLATED is the next safe solution one would turn towards since it is populated with a different mechanism.

It would be correct to develop in the direction if the script filename itself is contained in the SCRIPT_FILENAME path value, then the SCRIPT_FILENAME content is reported correctly. If it is not, using PATH_TRANSLATED is the next logical choice we can use. The best reference in this case would be PHP_SELF as it is populated by PHP itself. Using SCRIPT_NAME as a reference would be an error as it is affected by the same problem (reports cgi-system and/or php.cgi as well).

The following is the revised code and should work on both the non-CGI and the CGI PHP processor types.

When creating a shortcode i've seen code which uses the callback function however its not always needed as this example demonstrates:<?phpfunction wpsites_comment_form_shortcode() {ob_start();comment_form();$cform = ob_get_contents();ob_end_clean(); return $cform; }?>

When using brame buffer from time to time, you can see this warningWarning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sentOne of the many reasons may be in bad encoding of document. My experience, the document had header of utf-8 encoding but in fact it was win1252. After reconding to the utf-8 warning has disapeard.