What do ob_start and ob_gzhandler functions really do - php

I know that ob_start turns on output buffering, but I don't fully understand what it means. To me it means that it just stops outputting the script data.
Is this true? How does the browser output data in this case, do I have to use ob_end_flush() to turn it off in the end?
Since ob_gzhandler compresses web pages, how do browsers handle these pages?
I have seen ob_start("gzhandler") in code, since ob_gzhandler compresses web pages, what does ob_start("gzhandler") mean and how does it apply to both functions?
All help appreciated!

Output buffering means that instead of writing your output directly to the stdout stream, it is instead written to a buffer.
Then when the script finishes (or when you call ob_end_flush()), the contents of that buffer are written to stdout.
Using ob_gzhandler transforms the contents of the buffer before writing it to stdout, such that it is gzip compressed. (Browsers which support gzip compression reverse this on the opposite end, decompressing the content.)

Ok, let me explain it like this,
It is only one of the uses of the buffer system but I think it's kinda cool.
first I want you to look to this animation.
Operating System Start
When you have a php script that has a level based structure like this, for example you may write:
Connection established to database server..
Database selected : my_database
Data query started
Data query ended (found:200 rows)
...
etc. but if you don't use output buffering and flushing, you will see these lines when all of your script execution ends. But, when the thought is "I want to see what my script is doing when!", you first need to..
Sorry you first need to set implicit_flush to "on" at your php.ini file and restart your apache server to see all of this.
second, you need to open the output buffering (shorthand "ob") by "ob_start();", and then,
place anywhere on your code "echo" statements and after that "ob_flush();" commands to see your script running on realtime.
Later, it is also used for file based static content buffering like this:
place ob_start() at the start of your page (or the start of content you want to capture)
place ob_end_flush() at the end of your page (or the end of content you want to capture);
then $my_var = ob_get_contents(); to get all the HTML output that server creates and sends to the client into my_var variable and then use it as you want. Mostly it's saved to a file and by checking the file's last modification date, it's used as a static buffering.
I hope I could light some bulbs on your mind.

Related

php readfile() terminology

When we say that a function's result is sent to output buffer, it means that the result is not visible until echoed. And for functions that output directly, we use ob_start to direct the result to the output buffer (before it hits the browser as plain html) so that we may manipulate it, and then if desired, echo it.
The result of the function readfile() is directly visible, which is the contents of a certain text file, for example. then my question is:
Why it is mentioned in php documentation that readfile() sends the contents to the output buffer ?! (while in fact it is displayed directly).
Am I missing something?
When we say that a function's result is sent to output buffer, it means that the result is not visible until echoed. No it doesn't mean that!
Because it is sent to the output buffer, which (unless you've explicitly executed an ob_start() to buffer the output before sending it to the browser) is sent directly to the browser (or whatever).
All output is sent to the output buffer, but unless you've set the buffer to hold output before sending it, it gets sent.
EDIT
Of course, a webserver may be configured to cache output until a certain volume of data has been sent, but that isn't the same as PHP output buffering
Well, when the readfile() is executed, the output goes directly to stdout.
it is useful to know this behavior when php is used as a bash script:
#!/usr/bin/php
<?php
readfile("cool.txt");
// Output cool.txt whole content
It behave differently to file_get_contents from this view.
#!/usr/bin/php
<?php
file_get_contents("js.txt");
// No output!
$cool = file_get_contents("js.txt");
echo $cool;
// Output cool.txt

best way to output an image with php

I have a script called "image.php" that is used to count impressions and then print the image.
This script is called in this way:
<img src="path/image.php?id=12345" />
And it's used very often by my users, i see thousand of request per day
So I am looking to understand what is the best way to output the image at the end of this script:
Method 1 (actually in use):
header("Content-type: $mime"); //$mime is found with getimagesize function
readfile("$image_url");
exit;
Method 2 (pretty sure that is slowest):
header("Content-type: $mime");
echo file_get_contents("$image_url");
exit;
Method 3:
header('Location: '.$image_url);
exit();
Is method 3 better / faster than method 1?
Ok first of all Method 3 is way faster when redirected to the original file.
The first 2 methods need file access and read the file and also they don't use the browser cache!
Also when you store the rendered images, you can better let apache handle your static files.
Apache is way faster than PHP and it uses the right browser caching (3 or 4 times faster wouldn't be a suprise).
What happens is when you request a static file, apache send the Last-Modified header
If your client requests the same image again it sends the If-Modified-Since header with that same date. If the file isn't changed you server respond with an 304 Not Modified header without any data wich saves you a lot IO operations (Besides the ETAG header wich is also used)
For your impressions count of the image, you could create a cronjob that parses your apache access logs so the end-user won't even notice it. But in your case it's easier to count the impressions in your script and then redirect
Essentially, what readfile does is it reads the file directly into the output buffer while file_get_contents loads the file into the memory (string). So, when you output the results the data is copied from the memory into the output buffer, making it two times slower than readfile.

reducing ajax download time of a php generating a json string

I'm using an ajax call to download a php file producing a json string out of an sql query.
So as common, The request is for this .php and in the .php I'll do the query and echo the results as json-encoded string.
The file is about 850Kb (2500 records..), so it take a while to get it. I was searching for a way to reduce the download time. I was thinking of activating some kind of apache compression, just like css or js, but:
don't know if it's a good idea in this case
don't know exactly the htaccess syntax and mime type. And have I to compress a json mime or a php one?
Anyone has already solved this kind of issues?
:)
You should try using ob start with ob_gzhandler before outputting the result in your ajax script. This will compress your output and reduce render time.
ob_start("ob_gzhandler");
Read manual entry here: http://php.net/manual/en/function.ob-gzhandler.php
So my php code would be
<?php
//get all processing done.assuming $json_result holds output.
ob_start("ob_gzhandler");
echo $json_result;
ob_end_flush();
exit;
?>
Make sure that nothing is output to buffer in your script before hand like custom headers or any other prints.

how to use ob_start?

I am using PHPSavant templating system for a project and I am not sure how to use ob_start in this.
I have tried before .. for example,
page_header.php
-- ob_start();
page_footer.php
-- ob_end_flush();
But because now I am using a templating system.. am not sure where to put these function.
$template = new Savant3();
$template->some_var = $some_value;
$template->display('default_template');
the default_template contains all of and populate section using some variables (set to $template object). Should I be using ob_start and ob_end_flush where my html code is or to include on each and every php file which calls to this template?
Any ideas? thanks.
You don't have to force a flush, when the PHP script terminates the buffer is flushed.
As long as you put ob_start() at the beginning of your script, that's the best place. In fact you might want to force GZIP compression which will greatly speed up your page display. It seems most servers have GZIP disabled, but you can force it on in your PHP via:
ob_start('ob_gzhandler');
I guess that display method actually outputs the template, so that's the one you should wrap with ob_start and ob_end_flush. However I don't really see advantage of using ob_end_flush around single function call.

Get self web content

I have a php that makes some maintenance operations in my web and I need that the last operation it'll do is to save into a file the content of the screen. I mean, self content.
If the screen shows: "OP1 - OK ..." it has to save into a file this: "OP1 - OK ...".
Saving all the results of my operations into a variable will very hard for me. That's why I need to get the content of the self screen.
Is there any way to do this?
I think you can use an output buffer.
The following is from ob_start's php manual page:
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.

Categories