What's the use of ob_start() in php? - php

Is ob_start() used for output buffering so that the headers are buffered and not sent to the browser? Am I making sense here? If not then why should we use ob_start()?

Think of ob_start() as saying "Start remembering everything that would normally be outputted, but don't quite do anything with it yet."
For example:
ob_start();
echo("Hello there!"); //would normally get printed to the screen/output to browser
$output = ob_get_contents();
ob_end_clean();
There are two other functions you typically pair it with: ob_get_contents(), which basically gives you whatever has been "saved" to the buffer since it was turned on with ob_start(), and then ob_end_clean() or ob_flush(), which either stops saving things and discards whatever was saved, or stops saving and outputs it all at once, respectively.

I use this so I can break out of PHP with a lot of HTML but not render it. It saves me from storing it as a string which disables IDE color-coding.
<?php
ob_start();
?>
<div>
<span>text</span>
link
</div>
<?php
$content = ob_get_clean();
?>
Instead of:
<?php
$content = '<div>
<span>text</span>
link
</div>';
?>

The accepted answer here describes what ob_start() does - not why it is used (which was the question asked).
As stated elsewhere ob_start() creates a buffer which output is written to.
But nobody has mentioned that it is possible to stack multiple buffers within PHP. See ob_get_level().
As to the why....
Sending HTML to the browser in larger chunks gives a performance benefit from a reduced network overhead.
Passing the data out of PHP in larger chunks gives a performance and capacity benefit by reducing the number of context switches required
Passing larger chunks of data to mod_gzip/mod_deflate gives a performance benefit in that the compression can be more efficient.
buffering the output means that you can still manipulate the HTTP headers later in the code
explicitly flushing the buffer after outputting the [head]....[/head] can allow the browser to begin marshaling other resources for the page before HTML stream completes.
Capturing the output in a buffer means that it can redirected to other functions such as email, or copied to a file as a cached representation of the content

You have it backwards. ob_start does not buffer the headers, it buffers the content. Using ob_start allows you to keep the content in a server-side buffer until you are ready to display it.
This is commonly used to so that pages can send headers 'after' they've 'sent' some content already (ie, deciding to redirect half way through rendering a page).

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

this is to further clarify JD Isaaks answer ...
The problem you run into often is that you are using php to output html from many different php sources, and those sources are often, for whatever reason, outputting via different ways.
Sometimes you have literal html content that you want to directly output to the browser; other times the output is being dynamically created (server-side).
The dynamic content is always(?) going to be a string. Now you have to combine this stringified dynamic html with any literal, direct-to-display html ... into one meaningful html node structure.
This usually forces the developer to wrap all that direct-to-display content into a string (as JD Isaak was discussing) so that it can be properly delivered/inserted in conjunction with the dynamic html ... even though you don't really want it wrapped.
But by using ob_## methods you can avoid that string-wrapping mess. The literal content is, instead, output to the buffer. Then in one easy step the entire contents of the buffer (all your literal html), is concatenated into your dynamic-html string.
(My example shows literal html being output to the buffer, which is then added to a html-string ... look also at JD Isaaks example to see 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>

Following things are not mentioned in the existing answers :
Buffer size configuration
HTTP Header
and Nesting.
Buffer size configuration for 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.
The above code improve server performance as PHP will send bigger chunks of data, for example, 4KB (wihout ob_start call, php will send each echo to the browser).
If you start buffering without the chunk size (ie. a simple ob_start()), then the page will be sent once at the end of the script.
Output buffering does not affect the HTTP headers, they are processed in different way. However, due to buffering you can send the headers even after the output was sent, because it is still in the buffer.
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
Nicely explained here : https://phpfashion.com/everything-about-output-buffering-in-php

This function isn't just for headers. You can do a lot of interesting stuff with this. Example: You could split your page into sections and use it like this:
$someTemplate->selectSection('header');
echo 'This is the header.';
$someTemplate->selectSection('content');
echo 'This is some content.';
You can capture the output that is generated here and add it at two totally different places in your layout.

No, you are wrong, but the direction fits ;)
The Output-Buffering buffers the output of a script. Thats (in short) everthing after echo or print. The thing with the headers is, that they only can get sent, if they are not already sent. But HTTP says, that headers are the very first of the transmission. So if you output something for the first time (in a request) the headers are sent and you can not set any other headers.

Related

directing the output of a PHP function to a variable and preventing screen output [duplicate]

What is output buffering and why is one using it in PHP?
Output Buffering for Web Developers, a Beginner’s Guide:
Without output buffering (the default), your HTML is sent to the browser in pieces as PHP processes through your script. With output buffering, your HTML is stored in a variable and sent to the browser as one piece at the end of your script.
Advantages of output buffering for Web developers
Turning on output buffering alone decreases the amount of time it takes to download and render our HTML because it's not being sent to the browser in pieces as PHP processes the HTML.
All the fancy stuff we can do with PHP strings, we can now do with our whole HTML page as one variable.
If you've ever encountered the message "Warning: Cannot modify header information - headers already sent by (output)" while setting cookies, you'll be happy to know that output buffering is your answer.
Output buffering is used by PHP to improve performance and to perform a few tricks.
You can have PHP store all output into a buffer and output all of it at once improving network performance.
You can access the buffer content without sending it back to browser in certain situations.
Consider this example:
<?php
ob_start( );
phpinfo( );
$output = ob_get_clean( );
?>
The above example captures the output into a variable instead of sending it to the browser. output_buffering is turned off by default.
You can use output buffering in situations when you want to modify headers after sending content.
Consider this example:
<?php
ob_start( );
echo "Hello World";
if ( $some_error )
{
header( "Location: error.php" );
exit( 0 );
}
?>
I know that this is an old question but I wanted to write my answer for visual learners. I couldn't find any diagrams explaining output buffering on the worldwide-web so I made a diagram myself in Windows mspaint.exe.
If output buffering is turned off, then echo will send data immediately to the Browser.
If output buffering is turned on, then an echo will send data to the output buffer before sending it to the Browser.
phpinfo
To see whether Output buffering is turned on / off please refer to phpinfo at the core section. The output_buffering directive will tell you if Output buffering is on/off.
In this case the output_buffering value is 4096 which means that the buffer size is 4 KB. It also means that Output buffering is turned on, on the Web server.
php.ini
It's possible to turn on/off and change buffer size by changing the value of the output_buffering directive. Just find it in php.ini, change it to the setting of your choice, and restart the Web server. You can find a sample of my php.ini below.
; Output buffering is a mechanism for controlling how much output data
; (excluding headers and cookies) PHP should keep internally before pushing that
; data to the client. If your application's output exceeds this setting, PHP
; will send that data in chunks of roughly the size you specify.
; Turning on this setting and managing its maximum buffer size can yield some
; interesting side-effects depending on your application and web server.
; You may be able to send headers and cookies after you've already sent output
; through print or echo. You also may see performance benefits if your server is
; emitting less packets due to buffered output versus PHP streaming the output
; as it gets it. On production servers, 4096 bytes is a good setting for performance
; reasons.
; Note: Output buffering can also be controlled via Output Buffering Control
; functions.
; Possible Values:
; On = Enabled and buffer is unlimited. (Use with caution)
; Off = Disabled
; Integer = Enables the buffer and sets its maximum size in bytes.
; Note: This directive is hardcoded to Off for the CLI SAPI
; Default Value: Off
; Development Value: 4096
; Production Value: 4096
; http://php.net/output-buffering
output_buffering = 4096
The directive output_buffering is not the only configurable directive regarding Output buffering. You can find other configurable Output buffering directives here: http://php.net/manual/en/outcontrol.configuration.php
Example: ob_get_clean()
Below you can see how to capture an echo and manipulate it before sending it to the browser.
// Turn on output buffering
ob_start();
echo 'Hello World'; // save to output buffer
$output = ob_get_clean(); // Get content from the output buffer, and discard the output buffer ...
$output = strtoupper($output); // manipulate the output
echo $output; // send to output stream / Browser
// OUTPUT:
HELLO WORLD
Examples: Hackingwithphp.com
More info about Output buffer with examples can be found here:
http://www.hackingwithphp.com/13/0/0/output-buffering
The Output Control functions allow you
to control when output is sent from
the script. This can be useful in
several different situations,
especially if you need to send headers
to the browser after your script has
began outputting data. The Output
Control functions do not affect
headers sent using header() or
setcookie(), only functions such as
echo() and data between blocks of PHP
code.
http://php.net/manual/en/book.outcontrol.php
More Resources:
Output Buffering With PHP
As name suggest here memory buffer used to manage how the output of script appears.
Here is one very good tutorial for the topic
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
Buffers can be nested, so while one buffer is active, another ob_start() activates a new buffer. So ob_end_flush() and ob_flush() are not really sending the buffer to the output, but to the parent buffer. And only when there is no parent buffer, contents is sent to browser or terminal.
Nicely explained here: https://phpfashion.com/everything-about-output-buffering-in-php
UPDATE 2019. If you have dedicated server and SSD or better NVM, 3.5GHZ. You shouldn't use buffering to make faster loaded website in 100ms-150ms.
Becouse network is slowly than proccesing script in the 2019 with performance servers (severs,memory,disk) and with turn on APC PHP :) To generated script sometimes need only 70ms another time is only network takes time, from 10ms up to 150ms from located user-server.
so if you want be fast 150ms, buffering make slowl, becouse need extra collection buffer data it make extra cost. 10 years ago when server make 1s script, it was usefull.
Please becareful output_buffering have limit if you would like using jpg to loading it can flush automate and crash sending.
Cheers.
You can make fast river
or
You can make safely tama :)
This is a summary of output buffering in php. (XAMPP php.ini )
Output buffering is a mechanism for controlling how much output data
(excluding headers and cookies) PHP should keep internally before pushing that
data to the client. If your application's output exceeds this setting, PHP will send that data in chunks of roughly the size you specify. Turning on this setting and managing its maximum buffer size can yield some interesting side-effects depending on your application and web server. You may be able to send headers and cookies after you've already sent output through print or echo. You also may see performance benefits if your server is emitting less packets due to buffered output versus PHP streaming the output
as it gets it. On production servers, 4096 bytes is a good setting for performance
reasons.
Note: Output buffering can also be controlled via Output Buffering Control
functions.
Possible Values:
On = Enabled and buffer is unlimited. (Use with caution)
Off = Disabled
Integer = Enables the buffer and sets its maximum size in bytes.
Note: This directive is hardcoded to Off for the CLI SAPI
Default Value: Off
Development Value: 4096
Production Value: 4096
http://php.net/output-buffering
output_buffering=4096

What is the best way to generate the .html output base on your .php file? [duplicate]

What is output buffering and why is one using it in PHP?
Output Buffering for Web Developers, a Beginner’s Guide:
Without output buffering (the default), your HTML is sent to the browser in pieces as PHP processes through your script. With output buffering, your HTML is stored in a variable and sent to the browser as one piece at the end of your script.
Advantages of output buffering for Web developers
Turning on output buffering alone decreases the amount of time it takes to download and render our HTML because it's not being sent to the browser in pieces as PHP processes the HTML.
All the fancy stuff we can do with PHP strings, we can now do with our whole HTML page as one variable.
If you've ever encountered the message "Warning: Cannot modify header information - headers already sent by (output)" while setting cookies, you'll be happy to know that output buffering is your answer.
Output buffering is used by PHP to improve performance and to perform a few tricks.
You can have PHP store all output into a buffer and output all of it at once improving network performance.
You can access the buffer content without sending it back to browser in certain situations.
Consider this example:
<?php
ob_start( );
phpinfo( );
$output = ob_get_clean( );
?>
The above example captures the output into a variable instead of sending it to the browser. output_buffering is turned off by default.
You can use output buffering in situations when you want to modify headers after sending content.
Consider this example:
<?php
ob_start( );
echo "Hello World";
if ( $some_error )
{
header( "Location: error.php" );
exit( 0 );
}
?>
I know that this is an old question but I wanted to write my answer for visual learners. I couldn't find any diagrams explaining output buffering on the worldwide-web so I made a diagram myself in Windows mspaint.exe.
If output buffering is turned off, then echo will send data immediately to the Browser.
If output buffering is turned on, then an echo will send data to the output buffer before sending it to the Browser.
phpinfo
To see whether Output buffering is turned on / off please refer to phpinfo at the core section. The output_buffering directive will tell you if Output buffering is on/off.
In this case the output_buffering value is 4096 which means that the buffer size is 4 KB. It also means that Output buffering is turned on, on the Web server.
php.ini
It's possible to turn on/off and change buffer size by changing the value of the output_buffering directive. Just find it in php.ini, change it to the setting of your choice, and restart the Web server. You can find a sample of my php.ini below.
; Output buffering is a mechanism for controlling how much output data
; (excluding headers and cookies) PHP should keep internally before pushing that
; data to the client. If your application's output exceeds this setting, PHP
; will send that data in chunks of roughly the size you specify.
; Turning on this setting and managing its maximum buffer size can yield some
; interesting side-effects depending on your application and web server.
; You may be able to send headers and cookies after you've already sent output
; through print or echo. You also may see performance benefits if your server is
; emitting less packets due to buffered output versus PHP streaming the output
; as it gets it. On production servers, 4096 bytes is a good setting for performance
; reasons.
; Note: Output buffering can also be controlled via Output Buffering Control
; functions.
; Possible Values:
; On = Enabled and buffer is unlimited. (Use with caution)
; Off = Disabled
; Integer = Enables the buffer and sets its maximum size in bytes.
; Note: This directive is hardcoded to Off for the CLI SAPI
; Default Value: Off
; Development Value: 4096
; Production Value: 4096
; http://php.net/output-buffering
output_buffering = 4096
The directive output_buffering is not the only configurable directive regarding Output buffering. You can find other configurable Output buffering directives here: http://php.net/manual/en/outcontrol.configuration.php
Example: ob_get_clean()
Below you can see how to capture an echo and manipulate it before sending it to the browser.
// Turn on output buffering
ob_start();
echo 'Hello World'; // save to output buffer
$output = ob_get_clean(); // Get content from the output buffer, and discard the output buffer ...
$output = strtoupper($output); // manipulate the output
echo $output; // send to output stream / Browser
// OUTPUT:
HELLO WORLD
Examples: Hackingwithphp.com
More info about Output buffer with examples can be found here:
http://www.hackingwithphp.com/13/0/0/output-buffering
The Output Control functions allow you
to control when output is sent from
the script. This can be useful in
several different situations,
especially if you need to send headers
to the browser after your script has
began outputting data. The Output
Control functions do not affect
headers sent using header() or
setcookie(), only functions such as
echo() and data between blocks of PHP
code.
http://php.net/manual/en/book.outcontrol.php
More Resources:
Output Buffering With PHP
As name suggest here memory buffer used to manage how the output of script appears.
Here is one very good tutorial for the topic
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
Buffers can be nested, so while one buffer is active, another ob_start() activates a new buffer. So ob_end_flush() and ob_flush() are not really sending the buffer to the output, but to the parent buffer. And only when there is no parent buffer, contents is sent to browser or terminal.
Nicely explained here: https://phpfashion.com/everything-about-output-buffering-in-php
UPDATE 2019. If you have dedicated server and SSD or better NVM, 3.5GHZ. You shouldn't use buffering to make faster loaded website in 100ms-150ms.
Becouse network is slowly than proccesing script in the 2019 with performance servers (severs,memory,disk) and with turn on APC PHP :) To generated script sometimes need only 70ms another time is only network takes time, from 10ms up to 150ms from located user-server.
so if you want be fast 150ms, buffering make slowl, becouse need extra collection buffer data it make extra cost. 10 years ago when server make 1s script, it was usefull.
Please becareful output_buffering have limit if you would like using jpg to loading it can flush automate and crash sending.
Cheers.
You can make fast river
or
You can make safely tama :)
This is a summary of output buffering in php. (XAMPP php.ini )
Output buffering is a mechanism for controlling how much output data
(excluding headers and cookies) PHP should keep internally before pushing that
data to the client. If your application's output exceeds this setting, PHP will send that data in chunks of roughly the size you specify. Turning on this setting and managing its maximum buffer size can yield some interesting side-effects depending on your application and web server. You may be able to send headers and cookies after you've already sent output through print or echo. You also may see performance benefits if your server is emitting less packets due to buffered output versus PHP streaming the output
as it gets it. On production servers, 4096 bytes is a good setting for performance
reasons.
Note: Output buffering can also be controlled via Output Buffering Control
functions.
Possible Values:
On = Enabled and buffer is unlimited. (Use with caution)
Off = Disabled
Integer = Enables the buffer and sets its maximum size in bytes.
Note: This directive is hardcoded to Off for the CLI SAPI
Default Value: Off
Development Value: 4096
Production Value: 4096
http://php.net/output-buffering
output_buffering=4096

How to get all the HTML code generated via PHP at application-level

Is it possible, in PHP, to get all the generated HTML code, at the end of request processing?
What I want to achieve is to be able to retrieve (and, possibly, save/cache) the actual HTML that is about to be sent to users. I can do something similar in ASP.net with a Global.asax filter, that can access to low-level generated html code and modify/access it.
If needed, I can modify the web server settings and/or php interpreter settings (currently the web application runs on Apache+mod_php).
Use output buffering:
<?php
// Start buffering (no output delivered to the browser from now on)
ob_start();
// Generate the HTML
// ...
// Grab the buffer as a variable
$html_output = ob_get_contents();
// If you want to stop buffering and send the buffer to the browser
ob_end_flush();
// OR if you want to stop buffering and throw away the buffer
ob_end_clean();
Potential issues
There is a potential user impact as (depending on your web server) your page output is streamed to the user's browser as it's outputted (why you can start seeing really large pages before they've finished loading). But if you use the output buffer the user will only see the result after you've stopped buffering and outputted it.
Also, because you're buffering and not streaming your server will need to store what you're buffering which will use up additional memory (not a problem unless you're generating really large pages that exceed the memory limits of your PHP memory limit).
To avoid running out of memory you can chunk your buffering and write it to disc (or flush it to the user) at specific chunk sizes using a callback like this:
<?php
// The callback function each time we want to deal with a chunk of the buffer
$callback = function ($buffer, $flag) {
// Cache the next part of the buffer to file?
file_put_contents('page.cache', $buffer, FILE_APPEND & LOCK_EX);
// $flag contains which action is performing the callback.
// We could be ending due to the final flush and not because
// the buffer size limit was reached. PHP_OUTPUT_HANDLER_END
// means an ob_end_*() function has been called.
if ($flag == PHP_OUTPUT_HANDLER_END) {
// Do something different
}
// We could echo out this chunk if we want
echo $buffer;
// Whatever we return from this function is the new buffer
return '';
};
// Pass the buffer to $callback each time it reaches 1024 bytes
ob_start($callback, 1024)
// Generate the HTML
// ...
ob_end_clean();
I think what you would want to use is output buffering! At the start of your page use: ob_start();
At the end of the page you send to the client / browser using something like : ob_end_flush();
Before it is sent you can record that buffer to the db or text file

Output buffer in PHP won't work

For some time (serveral nights..) I've been trying to get a time-expensive script to output simple dots so I know it's still processing the script. Basically it's a cronjob which is going to run nightly to update cache-keys in a memcache server.
No matter what I try I can't get PHP to output the current buffer. What I want is to send the echo'd dots while processing the script. What am I missing to get it to work? I've also tried the flush() function... and also to use ini_set("output_buffering", 1024);
At the moment this is my set up:
# clean all open buffers
while(ob_get_level() != 0)
{
ob_end_clean();
}
ob_start();
// Several loops, taking some minutes...
for( ..loopconditions ..){
echo ".";
ob_flush();
}
ob_end_clean()
Are you debugging this in a browser? If so, it may not be a problem with the output buffering at all.
Every browser has a buffer of it's own and ultimately it decides when to start flushing it.
Mentioned in the manual page for flush():
flush() ... has no effect on any client-side buffering in the browser.
Even the browser may buffer its input before displaying it. Netscape, for example, buffers text until it receives an end-of-line or the beginning of a tag, and it won't render tables until the tag of the outermost table is seen.
Some versions of Microsoft Internet Explorer will only start to display the page after they have received 256 bytes of output, so you may need to send extra whitespace before flushing to get those browsers to display the page.
IIRC, if you're using php-cgi, output buffering doesn't work.
In console, it is easier to use PEAR Console_ProgressBar. It will do it for you.
Example from the docs:
<?php
require_once 'Console/ProgressBar.php';
$bar = new Console_ProgressBar('[%bar%] %percent%', '=>', ' ', 80, 7);
//do some processing here
for ($i = 0; $i <= 7; $i++) {
$bar->update($i);
sleep(1);
}
echo "\n";
?>
[=======================================> ] 57.14%
More examples in:
http://pear.php.net/manual/en/package.console.console-progressbar.php#example-124
http://pear.php.net/manual/en/package.console.console-progressbar.php#example-125

PHP immediate echo

I have quite a long data mining script, and in parts of it I echo some information to the page (during a foreach loop, actually.)
However I am noticing that the information is being sent to the browse not immediately as I had hoped, but in 'segments'.
Is there some function I can use after my echo to send all the data to the browser immediately?
Thanks.
You probably want flush(). However, PHP may be using output buffering. There are a few ways that this can change things, but in a nutshell, you can flush(), then ob_flush().
You can try using flush() after each echo, but even that won't guarantee a write to the client depending on the web server you're running.
Yes, padding your output to 1024 bytes will cause most browsers to start displaying the content.
But we also learn from #nobody's answer to question "How to flush output after each `echo` call?" that the 1024 bytes browser buffering effect only happens when the browser has to guess the character encoding of the page, which can be prevented by sending the proper Content-Type header (eg. "Content-Type: text/html; charset=utf-8"), or by specifying the content charset through appropriate html meta tags. And it worked as well for me in all browsers.
So basically, all one need to do is:
header('Content-Type: text/html; charset=utf-8');
ob_implicit_flush(true);
With no requirement for extra padding or flushing, which is of great cosmetic benefit for the code! Of course, headers have to be sent before any content, and one also has to make sure no output buffering is going on.
Problem definitely solved for me! Please (+1) #nobody's answer on the other question as well if it works for you. If, although, one still encounters problems, I suggest checking out the answers to that other question for other specific situations that might presumely prevent implicit flushing from working correctly.
Note also that some browsers won't start displaying anything until the body of the response contains a certain amount of data - like 256 or 1024 bytes. I have seen applications before that pad data with a 1024 character long comment near the top of the page, before they do a flush. It's a bit of a hack, but necessary.
This applies to Internet Explorer and Safari IIRC.
So,
If it is the first flush, make sure you have output at least 1024 bytes sofar (not including HTTP headers).
Call flush()
If you can determine that there is output buffering in place, issue ob_flush()
I like to just use
while (ob_get_level()) ob_end_flush();
near the start of my script somewhere, and then just
flush();
whenever I want to flush. This assumes that you don't want any output buffering at all, even if it was set up before your script (such as in a PHP.ini or htaccess configuration).
You should be able to use something like this to force output to be sent immeadiately. Put it at the part of the code you want the output to be sent.
flush();
ob_flush();
Phew! I finally found the answer to Google Chrome's buffer issue! Thanks to boysmakesh for the push in the right direction. Here's the function I use:
function buffer_flush(){
echo str_pad('', 512);
echo '<!-- -->';
if(ob_get_length()){
#ob_flush();
#flush();
#ob_end_flush();
}
#ob_start();
}
And this is how I call it:
show_view('global', 'header'); // Echos the <html><head>... tags and
// includes JS and CSS.
show_view('global', 'splash_screen'); // Shows a loading image telling
// the user that everything's okay.
buffer_flush(); // Pretty obvious. At this point the loading view shows
// up on every browser i've tested (chrome, firefox,
// IE 7 & 8)
show_view('global', 'main'); // Has a loop that echos "Test $i<br>" 5
// times and calls buffer_flush() each time.
show_view('global', 'footer'); // End the html page and use JQuery to
// fade out the loading view.
To perfectly work this out in Google chrome,
try this:
$i = 0;
$padstr = str_pad("",512," ");
echo $padstr;
while ($i <= 4){
$padstr = str_pad("",512," ");
echo $padstr;
echo "boysmakesh <BR> ";
flush();
sleep(2);
$i = $i + 1;
}
Ee are sending 512 bytes before sending EACH echo. Don't forget to put <BR> at the end of content before you flush. Else it won't work in Chrome but works in IE.
The data we padding is browser dependent. For some browsers it's enough to have 256 bytes but some need 1024 bytes. For chrome it is 512.
ignore_user_abort(TRUE); // run script in background
set_time_limit(0); // run script forever
$interval=150000;
$i = 0;
if(
strpos($_SERVER["HTTP_USER_AGENT"], "Gecko") or
strpos($_SERVER["HTTP_USER_AGENT"], "WebKit")
){
# important to change browser into quirks mode
echo '<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
}
function buffer_flush(){
echo "\n\n<!-- Deal with browser-related buffering by sending some incompressible strings -->\n\n";
for ( $i = 0; $i < 5; $i++ )
echo "<!-- abcdefghijklmnopqrstuvwxyz1234567890aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz11223344556677889900abacbcbdcdcededfefegfgfhghgihihjijikjkjlklkmlmlnmnmononpopoqpqprqrqsrsrtstsubcbcdcdedefefgfabcadefbghicjkldmnoepqrfstugvwxhyz1i234j567k890laabmbccnddeoeffpgghqhiirjjksklltmmnunoovppqwqrrxsstytuuzvvw0wxx1yyz2z113223434455666777889890091abc2def3ghi4jkl5mno6pqr7stu8vwx9yz11aab2bcc3dd4ee5ff6gg7hh8ii9j0jk1kl2lmm3nnoo4p5pq6qrr7ss8tt9uuvv0wwx1x2yyzz13aba4cbcb5dcdc6dedfef8egf9gfh0ghg1ihi2hji3jik4jkj5lkl6kml7mln8mnm9ono -->\n\n";
while ( ob_get_level() )
ob_end_flush();
if(ob_get_length()){
#ob_flush();
#flush();
#ob_end_flush();
}
#ob_start();
}
ob_start();
do{
if($i<10){
buffer_flush();
echo ". ";
buffer_flush();
usleep($interval);
} else {
echo sprintf("<pre>%s</pre>", print_r($_SERVER,true));
break;
}
$i++;
}while(true);
Running php 5.5 on IIS 7, IE 11 (win server) I found this worked as the opening lines of the file. Note putting the while statement before the header caused a header already written error.
header('Content-Type: text/html; charset=utf-8');
while (ob_get_level()) ob_end_flush();
ob_implicit_flush(true);
Further references to ob_flush() in the script caused a buffer does not exist error.
This worked fine when I was processing a file and sending sql statements to the browser, however when I hooked up the db (ms server 2008) I had no input returned till the script had completed.
this combination finally worked for me, based on thomasrutter's answer
while (ob_get_level()) ob_end_flush();
ob_implicit_flush(true);

Categories