Showing posts with label PHP OUTPUT Buffering. Show all posts
Showing posts with label PHP OUTPUT Buffering. Show all posts

Monday, 24 September 2018

Output buffering in php and apache

Output Buffering

Output buffering is processing mechanism where the output being generated by a program is held in a place till its size reaches a limit or the generation is complete. Only after, will the output be send to its destination.
In php for example, doing and echo generates some output. Now this output might be buffered. If its not, then the output will appear on your browser as soon as it is generated. If it is buffered then the output of all echo statements is collected and shown to you once the php script has finished execution.
Output buffering is done for various reasons, like speeding up page load time, doing special processing to the generated content etc. However there are many cases when we want to see the output of the program in realtime as it is being generated. For example to monitor the progress of some task.

Buffering Points

In a php+apache setup, output buffering can happen at many places and finding it out can take some time. The execution is done somewhat like this
Browser <===> Apache <===> Php handler <===> Php interpreter/process

Php

Now the output can get buffered at any of the 4 places shown above. We shall ignore the browser for now. The first place where the output can get buffered is php itself. Php has a setting called output_buffering. This can used to specify the amount of data to buffer before sending to it back to apache.

Apache/Webserver

Another place where the output can get buffered is apache or the webserver. Apache can buffer the output to compress it using mod gzip/deflate for example. Compresses reduces content size considerably and saves bandwidth and speeds up page load time by a large factor.
So to disable output buffering in apache, check if gzip or deflate are enabled and active or not. Generally deflate is kept enabled and the compression is controlled via the htaccess files. So check them accordingly.

Php Handlers

Php handlers are the secret hidden place where the content can buffered and the user might not notice ever. Yeah, php handlers like mod_fastcgi/mod_fcgid buffer the content too.
If you have turned off buffering in both apache and php entirely, but still the output is getting buffered, then most likely its the handlers where the output is getting buffered.
Mod fcgid has a directive called FcgidOutputBufferSize that can be used to specify the output buffer size. So if you are using fcgid then set this value to 0 to disable output buffering totally.
Mod fastcgi also buffers output by default and to turn it off use the "flush" option in the Fastcgi settings specified in vhosts block of apache.
Mod_php and Cgi do not buffer output so no issues there.
With nginx the HttpFastcgiModule also buffers content. Check out the documentation for more information.

Monday, 17 September 2018

Output buffering with PHP

Output is not buffered by default with PHP and the contents of the script is sent to the browser in chunks as it is created. PHP's output buffering functions buffer the output giving control over when content is sent, allowing it to be compressed and allowing a mixture of headers and content to be coded without getting those "Cannot modify header information - headers already sent" error messages.

Cannot modify header information - headers already sent

The above error message is displayed when some content has already been sent to the web browser and then a header is set, such as setting a cookie, doing a page redirect and so on. Headers must be set before sending any content which is the reason for the error.
While it is best practise to ensure all headers at set before sending any content, sometimes it can be simpler to just use output buffering which will eliminate the error message. When output buffering is enabled, all the headers will be sent but the content will only be sent either at the end of the script or when explicitly done by the script.

How to enable output buffering

To enable output buffering simply add the following to the start of the PHP script:
ob_start();
To enable gzip compression to make the page content smaller do this:
ob_start("ob_gzhandler");
Note that if the gzhandler is being used, then using any of the other buffering functions as shown in examples below probably won't work as expected and may cause issues with the browser rendering the page.
Nothing further needs to be done in the script after making one of the two function calls above; when it gets to the end buffering is complete and the entire content is sent to the browser either as plain text, or gzip encoded with the appropriate headers.

Empty the output buffer

To empty the current contents of the output buffer do this:
ob_end_clean()

Get the contents of the output buffer

It is possible to get the contents of the output buffer as a string and do something with it, such as save it to a file, send it as an email, log it and so on. Some PHP functions echo the output rather than return it as a string and sometimes it can be useful to use output buffering to get this content.
The first example below will get the content and return it into the $content variable. The current buffer is unaffected by this function call:
$content = ob_get_contents();
The second example gets the content but empties the buffer, discarding the content from it:
$content = ob_get_clean();

Explicitly flush the buffer

The buffer can be explicitly flushed at any time using one of several functions.
The first example below flushes the buffer by sending the buffered content to the browser and the emptying the buffer. Any further output will continue to be buffered.
ob_flush();
The second example flushes the buffer by sending the content to the browser, emptying the buffer, and no longer buffering. Any further content is sent directly to the browser.
ob_end_flush();
The final example flushes the output to the browser in the same way as ob_end_flush() and also returns it as a string:
$content = ob_get_flush();

Further reading

Be sure to read the PHP manual for further output buffering examples and functions. The user comments on many of the function reference pages are very useful.


Related posts: