i know those methods related to output buffering:
<?php
ob_start();
// some code
ob_end_flush();
ob_end_clean();
but i can't figure out why will i need the length of the output buffer. there is one question here is SOF about measuring the bandwidth of the user ,although that calculation will need to measure pictures and other files which is not addressed.
i did check the PHP manual and the "why" is not there.
Answering "why to use it". In order to answer this, we must first understand why we need to use ob_start.
Usually it is used for two purpose:
When we want to send HTTP headers, but we are not sure, that there is no rendering before(the first output will trigger header sending, so if you use, echo for example, before header, the later won't work)
When we want to send our output by chunks for performance. (your code can be written with a lot of echo or print, and usually they outputing only small data, so you are sending small portions of data back to browser, which is affecting performance.)
So now you can start to guess, why we need to use ob_get_length(). For example: i want to send my output by large chunks, so i am enabling output buffering and with the help of ob_get_lengthi can control how many data i can write to buffer, before sending it.
ob_get_length will return the length of the contents in the output buffer..
Here is simple example..
<?php
ob_start();
echo "Hello ";
$len1 = ob_get_length();
echo "World";
$len2 = ob_get_length();
ob_end_clean();
echo $len1 . ", ." . $len2;
?>
The above example will output: 6, 11
Updated:
ob_get_length() is helpful if you want to send a custom HTTP Content-Length header - although that is for advanced users only!
Related
I have the code below code that works correctly as what i want. It does not send any output on browser that is what i exactly want.
ob_start();
echo "test";
echo "test";
$output = ob_get_clean( );
But problem is in my below code. below code start sending the output on the browser even i have $output = ob_get_clean( ); at the end
ob_start();
for($i=0;$i<=10000000;$i++){
echo $i."<br/>";
}
$output = ob_get_clean( );
I am unable to understand the concept of output buffering. everyone say you can control the output and send the output when you want but my above script start sending output to the browser.
There's a limit to how much there can be buffered which by default is 4KB so you are hitting the maximum with your script. If you want to use it for a larger buffer you have to edit your php.ini settings to reflect that. To quote from the PHP docs
You can enable output buffering for all files by setting this directive to ‘On’. If you wish to limit the size of the buffer to a certain size – you can use a maximum number of bytes instead of ‘On’, as a value for this directive (e.g., output_buffering=4096). As of PHP 4.3.5, this directive is always Off in PHP-CLI. source
The PHP doc is quite technical on the subject so I found this blog post which explains the bits and tricks to output buffering:
Streaming and Output Buffering
PHP has many different ways to print things, and I don't understand the difference between them. There are at least the following:
stdout and stderr. These can be denoted as php://stdout and php://stderr. There are also constants STDOUT and STDERR, and I think these refer to the same thing. So far, so good; these are standard.
php://output. What is this? Where does it go? Is it a synonym for php://stdout, or something else? The docs say it writes "to the output buffer mechanism", but I don't know where the contents of this buffer go after that.
print and echo. The docs say that these print to php://output. They are both language constructs, but at a guess, the difference is that print is an expression, but echo is a statement.
printf and many friends. Do these all also go to php://output?
Escaping. There are lots of alternative syntaxes for escaping, but I'm guessing they all have the same semantics. But what are the semantics? Where does the escaped text get printed to? Also to php://output? Currently, I understand ?>foo<?php as syntactic sugar for echo 'foo';; is this correct?
Are there more ways of doing output? What exactly are the differences? What settings and environments affect their behavior?
First off, stdin and stdout are your standard input and output streams that most languages have. If you were to run php though the console you could create a script like this:
$input = fopen("php://stdin", "r");
$line = trim(fgets($input));
echo $line;
or
$line = trim(fgets(STDIN));
echo $line;
These scripts will both open the standard console input and allow you to enter input terminated by a return.
Now from the command line 'php://stdout' and 'php://output' function rather similarly, assuming you don't have output buffering on by default, and will both give you standard output to the console. By doing something like:
$out = fopen("php://stdout", "w");
fwrite($out, "Hello World!");
or
$out = fopen("php://output", "w");
fwrite($out, "Hello World!");
Both of these will output Hello World! to the console as expected.
Now as for output buffering is concerned, it is by default set to 0 in the php configuration file(meaning it is disabled). Output buffering is a way of 'holding back' output whether it be written to the console or to a browser. If you use the ob_start function to turn on output buffering none of your output will go to the console/browser. Instead it will be put in the buffer and wait until the buffer reaches it's max capacity(or until you flush it manually), then it will dump the buffer contents to stdout.
On to print and echo. These are not real functions they are language constructs where echo does not return anything and print always returns 1. The main difference between the two is that echo can print multiple strings delimited by a comma.
Both print and echo print to the output buffer but since, by default, output buffering is disabled they appear to output directly to the console/browser.
Now as for the differences between php://output and STDOUT. There is only a noticeable difference if output buffering is turned on. If it is turned on then stdout output will still go to the standard output of the console/browser but php://output will go to the buffer until the buffer reaches it's capacity or you manually flush the buffer. This example illustrates the difference:
<?php
$out1 = fopen("php://stdout", 'w');
$out2 = fopen("php://output", "w");
ob_start(); //enable output buffering
echo "This is an echo\n";
print "This is a print\n";
printf("%d", 52);
echo "\n";
fwrite($out1, "Hello World!");
fwrite($out2, "\nGoodbye World!");
ob_end_clean(); //turn off output buffering and get rid of it's contents without printing them
?>
Notice how only Hello World! is output rather than the rest of the output statements in this script. If we comment out the ob* statements than we see that all of the other output was put in the output buffer. If we used ob_end_flush() at the end of the script instead we would Hello World! followed by all of the output from the output buffer, in the order than it was put into the buffer. Furthermore, from this example we can also see that printf also prints to the output buffer(probably using the underlying functionality of echo or print) and I'm assuming that is how all the rest of the formatting functions work but don't quote me on that.
As far as the escaping you are referring to, that is usually done to display html conditionally or when you have an array of stuff that you don't want to hard code. For instance consider:
<select>
<? foreach($array as $option){ ?>
<option value="<?=$option?>"><?=$option?></option>
<? }?>
</select>
This code could be used to output an array of options for a select without hard coding values and without the need to use write echo or print or print statements(note echo is used indirectly via the syntax ).
Surprisingly this output is also written to the output buffer and includes any whitespace you enter in this region but only if you are at the console(browsers interpret whitespace differently). Also, escape characters like \n, \t, etc.. have no meaning in this context and are interpreted exactly as they are seen. This can be seen by modifying the code above to:
<?php
$out1 = fopen("php://stdout", 'w');
$out2 = fopen("php://output", "w");
//ob_start();
echo "This is an echo\n";
print "This is a print\n";
printf("%d", 52);
echo "\n";
?>
Jelly Bean
<?php
fwrite($out1, "Hello World!");
fwrite($out2, "\nGoodbye World!");
//ob_end_clean();
?>
As you can see Jelly Bean is printed when the output buffering statements are commented out, but if you comment them back in Jelly Bean doesn't appear in the output. Again if you uncomment the ob* statements and make the last statement ob_end_flush() you will see all of the input from the buffer output to stdout, in the order that it was put into the buffer.
This is a sample code from the book I am reading:
ob_start();
include("{$path}.ini");
$string = ob_get_contents();
ob_end_clean();
$pairs = parse_ini_string($string);
My question is, how does ob_get_contents() know what to get contents from? ({$path}.ini in this situation)?
ob_get_contents simply gets the contents of the output buffer since you called ob_start(). Essentially, an output buffer in PHP catches anything that would have been output to the browser (excluding headers). It's useful in cases where you may need to filter some output, or you're using a PHP method (such as var_dump) that writes output directly to screen, and you would instead like the return value of the method in a string.
In this case, because you're include()ing the .ini file, it's contents will be essentially output to screen, and ob_get_contents() will get the content of the file.
If you were to put echo "I'm a little teapot short and stout"; underneath the include, this would also be included in $string after the body of the .ini file.
In your specific case, however, output buffering is an unnecessary overhead, simply use file_get_contents on the .ini file. I'm not sure why a book would even have this code in it at all.
The "ob" stands for "output buffer". When you call ob_start(), PHP reroutes all output (using echo, etc) to the output buffer. Then you can use the other ob_* functions to retrieve and/or clear the buffer contents.
In your example, it will buffer any output generated by the file referenced by "{$path}.ini". When you include it, its output is added to the buffer, and when you call ob_get_contents(), it retrieves the contents of the buffer.
From PHP:
ob_start — Turn on output buffering
ob_get_contents — Return the contents of the output buffer
ob_end_clean — Clean (erase) the output buffer and turn off output buffering
Now, ob_get_contents can collect all buffer that outputted.
[1] http://www.php.net/manual/en/book.outcontrol.php
ob_get_contents() is getting everything that is echoed after calling ob_start() function, so there is not anything special about {$path}.ini - you are required to echo data you want to collect (yes, even outputs of simple echo or print_r calls will be collected - sometimes useful for debugging simple scripts).
You may understand ob_start() function as a simple redirection from screen to (invisible) PHP internal buffer which is later read by ob_get_contents(). So you will be able to redirect anything that you may see on the screen without calling ob_start() function (even the whole web pages).
In my website(running with drupal) the ob_flush function takes a long time(between 10 - 100 secs) to be executed. How do I find out why? What can cause this so long time?
Try this:
ob_start();
//Your code to generate the output
$result = ob_get_contents(); //save the contents of output buffer to a string
ob_end_clean();
echo $result;
It is run quick for me.
[You may want to tag your question with Drupal, since this feels like it might be a Drupal issue. Specifically, I suspect that when you flush the buffer, you're writing to an outer buffer, which triggers a ton of hooks to be called to filter the data you've just written.]
I suspect that your problem is nested buffers. Drupal really likes buffers and buffers everything all over the place. Check the result of:
echo "<pre>\nBuffering level: ";
. ob_get_level() .
. "\nBuffer status:\n"
. var_dump(ob_get_status(TRUE))
. "\n</pre>";
If you've got nested buffers, then I suspect ob_flush() will do nothing for you: it just appends the contents of your inner buffer into the next outermost layer of buffering.
Nested buffers can come from Drupal itself (which the above will show), or from the settings for zlib-output-compression and output_buffering (try twiddling those, see if it changes anything).
If your buffers are not nested, and the above settings do not help, then you may also want to split the operation into pieces, and run the profiler there, to see which part is taking the time:
$data = ob_get_contents(); // Return the contents of the output buffer.
ob_clean(); // Clean (erase) the output buffer.
ob_end(); // Close the buffer.
echo($data); // Output our data - only works if there's no outer buffer!
ob_start(); // Start our buffer again.
The question then becomes, though, "what are you trying to accomplish?" What do you think ob_flush() is doing here? Because if the answer is "I want to push everything I've done so far to the browser"... then I'm afraid that ob_flush() just isn't the right way.
SET
output_buffering = Off
in php.ini
use
<?ob_start();?>
at the beginning of the page and
<?ob_flush();?>
at the end of the page, to solve this problem.
Firstly, I want to echo text and ,after 5 seconds,I want to echo another text.
So I write...
<?php
echo 'Text';
flush();
sleep(5);
flush();
echo 'Another Text';
?>
But I see both of (Text Another Text ) after 5 seconds.How can I do for this?
From documentation
Several servers, especially on Win32, will still buffer the output from your script until it terminates before transmitting the results to the browser.
So you see both TextAnother Texttogether.
Take a look at output buffering.
Have you started output buffering at some time? If so, you need to use ob_end_flush() to flush.
Switch off output buffering if you have it on or call ob_flush() too. Any output compressing (like gzip) will also mess it up. If it doesn't work try modifying these two php.ini directives to:
output_buffering = off
zlib.output_compression = off