Shall I use output buffering (ob_start) or not - php

I have amended my PHP code in order to avoid using output buffering after finding out that it denotes a poor coding pattern. But still am using it where it is needed inevitably.
But, some articles say that using output buffering is beneficial as it combines the output into one , by default the output is broken into html and headers separately and is then displayed on the browser, but output buffering eliminates this breakage process, thus augmenting the speed of output display to the end user.
All this article stuff has left me in a dilemma to use or completely avoid output buffering. Am not sure if am completely right about its working and the points I have mentioned.
So please guide me accordingly.

There are times where the use of output buffering is a good thing to use, but to use it as lots of people do (the lazy way of not having to send headers before output for example) is not the right time.
The example you give, I do not know much about, but if its optimal, it might be one of the times where its good to use.
Its not forbidden to use ob_start(), its just the "wrong way" to use it the way I stated earlier.
The optimization you mention feels like a very low-level optimization, you might get a tad bit 'quicker' output, but there is usually a lot of other optimizations in a standard php-script that could speed it up before that is worth looking at!
edit:
Example of a small script that don't use send headers before output vs one that do:
<?php
$doOutput = true;
$doRedirect = true;
$output = "";
if($doOutput == true){
// $doOutput is true, so output is supposed to be printed.
$output = "Some output yay!";
}
if($doRedirect == true){
// but $doRedirect is also true, so redirect will be done.
header("location:anotherpage.php"); // This will not produce an error cause there was no output!
exit();
}
// The echo below will not be printed in the example, cause the $doRedirect var was true.
echo $output;
Instead of (this case will produce a header sent after output error):
<?php
$doOutput = true;
$doRedirect = true;
if($doOutput == true){
//Output will be printed, cause $doOutput is true.
echo "Some output yay!";
}
if($doRedirect == true){
// but $doRedirect is also true, so redirect will be done.
header("location:anotherpage.php"); // This will produce an error cause output was already printed.
exit();
}
edit2: Updated with a more obvious example!

Related

Why need use ob_start() with include()?

Why is recommended use ob_start() in PHP language when you need include other PHP (or template) file?
This is bad:
require_once( dirname( __DIR__ ) . '/views/file.php' );
This is good:
ob_start();
require_once( dirname( __DIR__ ) . '/views/file.php' );
$output = ob_get_clean();
return $output;
But i don't get why
There is no such recommendation, use it if you think its necessary.
ob_start() tells PHP to start buffering output, any echo or other output by any means will be buffered instead of sent straight to the client.
This can be used for many purposes, one of them is being able to send headers even after producing output, since the output wasn't sent yet thanks to buffering.
In this particular piece of code you have, you are using output buffer to catch the output generated by your included file and storing it to a variable, instead of sending it to the client.
It would be hard to say without understanding a little more about your program, as well as who is telling you to do this. For one thing, the return $output line at the bottom--what are you returning from?
I can think of many reasons you'd want to include scripts this way.
In PHP, the ob_* functions deal with output buffering, that is, capturing anything that gets printed to the page/screen your PHP code is running in as a string.
This may be necessary because a very common pattern in classic PHP is to write straight HTML outside of any <?php tags. When you output text this way, it gets sent directly to the screen, bypassing any intermediate processing that you may want to do with it. It's also possible that a programmer may want to define all of their includes in one place, so that they can be switched out easily, and then reference the text to be output as a variable later in the script.
It may also be a way to prevent includes that don't output any text from accidentally outputting white space, making it impossible to change headers later on in the script. I've had problems before with a large code base in which every include had been religiously closed with a ?> and may or may not have included white space afterward. This would have solved the problem with comparatively little effort.
In programming, there are often many different ways to do things, and there's not always one of them that's "right." The end goal is to create something that does its job, is maintainable, and can be comprehended by other programmers. If you have to write a couple of extra lines of code in pursuit of maintainability, it's worth it down the line.
ob_start() is a function that begins output buffering, ob_get_clean(); flushes the buffer, and it looks like you are returning it from a function.
This allows any print or echo statements to be added to the buffer, and then all stored to a variable and returned and printed elsewhere in your application.

PHP/HTML output: echo vs return, output buffering, and syntax highlighting challenges

I prefer to write html outside of php tags, so eclipse can display the html with proper syntax highlighting. The concatenation method is harder to write and doesn't highlight (see the two examples below).
I apologize for the length. These examples are very simple, so it should be an easy read.
I DON'T like this, too many 'quotes' and $o's, and no syntax highlighting!:
<?php
display($something){
$o = '';
$o .= '<div>';
$o .= $something;
$o .= '</div>';
return $o;
}
// I want to be able to do this:
echo display(display('something'));
This gives a function the chance to finish the closing <tag> or even add additional html afterwards. The above example is functionally what I'm looking to do, but for these reasons ('quotes', $o's, and syntax highlighting) I haven't created a system like this.
The following example is how I prefer to write html, but I can't nest output, because it doesn't return!
<?php
function display($something){ ?>
<div>
<?=$something?>
</div>
<?php }
// I'd like to do this, but I can't
display(display('this doesn't return anything to the first function call...'));
This is where output buffering comes in, I'll get back to that in a second...
What I'm envisioning:
I'd like to be able to use func_get_args() to accomplish something like this (note, this will apply to OOP objects, just keeping it simple here):
<?php
some_panel( title_style_1('Sample Header'),
panel_content(you_tube($vid_id)),
small_img_frame($img_src) );
You'd basically be able to take any of these output functions and nest them any way you like. Just like you can put any <div> inside any <p> and vice versa. Only problem is, you have to make sure you close the tags... And, in this case, you could add any markup at the end or in between children.
This is where the output buffering comes in
<?php
function display($something){
ob_start(); // <---- Start buffer ?>
<div>
<?=$something?>
</div>
<?php return ob_end_clean(); // <------ Return output
}
// Now I can do this!!!
echo display(display('this should work!'));
And, drum roll please.... THE QUESTION:
If I'm repeatedly buffering potentially hundreds or even thousands of times per request, is this going to be a performance hit? I've read posts that warn against output buffering due to:
Reliability: If somewhere else a buffer was started, from what I read, it sounds like these nest and can potentially conflict.
Maintainability: If a buffer is started, you have to guarantee it will be stopped.
For my system, if output buffering is started and stopped in the same function call, these things seem to be OK. It's the excessive iteration of potentially 1000's of items that each start/stop output buffering for a single <li> that I'm worried about.
Also, if anyone knows of any frameworks or better ways to do what I'm trying to do, any suggestions would be appreciated!
How about nesting output via… output?
<?php
function foo($itemName) {
?>
<div class="item">
<?php bar($itemName); ?>
</div>
<?php
}
function bar($itemName) {
?>
<h1><?= $itemName ?></h1>
<p>Hello, world!</p>
<?php
}
?>
But to answer the rest of the question: benchmark it! Output buffering is usually not a problem, but it could very well be anybody’s bottleneck. It depends.
If you find yourself doing this sort of thing a lot, consider breaking it out in to several files or using a template system. Or not PHP.
Output buffering is probably a wash, it may even improve performance. The CPU wasted buffering is saved in doing less I/O. Socket writes are actually thousands of instructions. The only time it could become a problem is when the amount of output would adversely impact memory usage. And if you are buffering many megabytes of output you probably need to look into some form of streaming.
Here's an older post on this topic PHP output buffering - sounds like a bad idea, is it?

Output Buffer and die() / exit() function?

I hope everyone's holidays are going well.
Another PHP related question here. I am using output buffers in my script, for what I have recently learned is an invalid reason (so I can pass headers later in the script). I now realize that I should be storing all output in a variable or some other sort of storage until I am ready to output at the end of the script instead of using output buffers. Unfortunately, I have already coding these functions and the spontaneous output of html into my pages already. I was hoping to be able to fix this problem in version 2 of the script, as I have strict deadlines to meet with this version.
To the question at hand. I was planning to do this, but apparently die() and exit() functions do not work so well with output buffers? I have exit() after all of my error messages, and instead of ending the execution at that point, it seems the script keeps going due to the output buffer. I have tested this hypothesis by removing the output buffers and the exit() functions work as expected.
Is there a way I change this behaviour, or should I go back to the drawing board and begin replacing my older pages? Also, can someone please explain to me why we should keep output till the end? I'm always interested in learning.
Thanks in advance everyone! Enjoy the last few days of 2010!
While I'll leave the headier and more abstract questions to more intelligent minds than I, I would recommend that you create a wrapper exit() function to simplify the code when you have errors.
i.e-
if(!$good)
{
trigger_error('bleh', E_USER_WARNING);
errorExit();
}
function errorExit()
{
ob_flush();
exit();
}
And replace all your exits with that function call and that way the buffer is flushed and the program will exit at the proper time.
Difference between header and the actual page content is basically only the position where they occur.
As the name suggests, header is in the beginning of the output. After that two carriage/returns (enter symbols) are sent and everything after that is presumed to be content.
Therefore, if you echo something and then want to change the header, it cannot be done. The content part already closed header part. What you would send as new header would now display as plain text (should PHP interpreter not stop you, which it does).
As for the other part of the question, ob_flush is a good solution as noted by Patrick.

PHP - To echo or not to echo?

What is more efficient and/or what is better practice, to echo the HTML or have many open and close php tags?
Obviously for big areas of HTML it is sensible to open and close the php tags. What about when dealing with something like generating XML? Should you open and close the php tags with a single echo for each piece of data or use a single echo with the XML tags included in quotations?
From a maintenance perspective, one should have the HTML / XML as separate from the code as possible IMO, so that minor changes can be made easily even by a non-technical person.
The more a homogeneous block the markup is, the cleaner the work.
One way to achieve this is to prepare as much as possible in variables, and using the heredoc syntax:
// Preparation
$var1 = get_value("yxyz");
$var2 = get_url ("abc");
$var3 = ($count = 0 ? "Count is zero" : "Count is not zero");
$var4 = htmlentities(get_value("def"));
// Output
echo <<<EOT
<fieldset title="$var4">
<ul class="$var1">
<li>
$var2
</li>
</ul>
</fieldset>
EOT;
You will want to use more sensible variable names, of course.
Edit: The link pointed out by #stesch in the comments provides some good arguments towards using a serializer when producing XML, and by extension, even HTML, instead of printing it out as shown above. I don't think a serializer is necessary in every situation, especially from a maintenance standpoint where templates are so much more easy to edit, but the link is well worth a read. HOWTO Avoid Being Called a Bozo When Producing XML
Another big advantage of the separation between logic and content is that if transition to a templating engine, or the introduction of caching becomes necessary one day, it's almost painless to implement because logic and code are already separated.
PHP solves this problem by what is known as heredocs. Check it out please.
Example:
echo <<<EOD
<td class="itemname">{$k}s</td>
<td class="price">{$v}/kg</td>
EOD;
Note: The heredoc identifer (EOD in this example) must not have any spaces or indentation.
Whichever makes sense to you. The performance difference is marginal, even if a large echo is faster.
But an echo of a big string is hard to read and more <?php echo $this->that; ?> tell a story :)
echo sends its argument further down the request processing chain, and eventually this string is sent to the client through a say, network socket. Depending on how the echo works in conjunction with underlying software layers (e.g. webserver), sometimes your script may be able to execute faster than it can push data to the client. Without output buffering, that is. With output buffering, you trade memory to gain speed - you echos are faster because they accumulate in a memory buffer. But only if there is no implicit buffering going on. One'll have to inspect Apache source code to see how does it treat PHPs stdout data.
That said, anything below is true for output buffering enabled scripts only, since without it the more data you attempt to push at once the longer you have to wait (the client has to receive and acknowledge it, by ways of TCP!).
It is more efficient to send a large string at once than do N echos concatenating output. By similar logic, it is more efficient for the interpreter to enter the PHP code block (PHP processing instruction in SGML/XML markup) once than enter and exit it many times.
As for me, I assemble my markup not with echo, but using XML DOM API. This is also in accordance with the article linked above. (I reprint the link: http://hsivonen.iki.fi/producing-xml/) This also answers the question whether to use one or many PHP tags. Use one tag which is your entire script, let it assemble the resulting markup and send it to the client.
Personally I tend to prefer what looks the best as code readability is very important, particularly in a team environment. In terms of best practice I'm afraid I'm not certain however it is usually best practice to optimize last meaning that you should write it for readability first and then if you encounter speed issues do some refactoring.
Any issues you have with efficiency are likely to be elsewhere in your code unless you are doing millions of echo's.
Another thing to consider is the use of an MVC to separate your "views" from all of your business logic which is a very clean way to code. Using a template framework such as smarty can take this one step further leading to epic win.
Whatever you do, don't print XML!
See HOWTO Avoid Being Called a Bozo When Producing XML
I've made myself the same question long time ago and came up with the same answer, it's not a considerable difference. I deduct this answer with this test:
<?
header('content-type:text/plain');
for ($i=0; $i<10; $i++) {
$r = benchmark_functions(
array('output_embeed','output_single_quote','output_double_quote'),
10000);
var_dump($r);
}
function output_embeed($i) {
?>test <?php echo $i; ?> :)<?
}
function output_single_quote($i) {
echo 'test '.$i.' :)';
}
function output_double_quote($i) {
echo "test $i :)";
}
function benchmark_functions($functions, $amount=1000) {
if (!is_array($functions)||!$functions)
return(false);
$result = array();
foreach ($functions as $function)
if (!function_exists($function))
return(false);
ob_start();
foreach ($functions as $idx=>$function) {
$start = microtime(true);
for ($i=0;$i<$amount;$i++) {
$function($idx);
}
$time = microtime(true) - $start;
$result[$idx.'_'.$function] = $time;
}
ob_end_clean();
return($result);
}
?>

How to clear previously echoed items in PHP

In php, is there any way to clear/remove all previously echoed or printed items?
For example:
<?php
echo 'a';
print 'b';
// some statement that removes all printed/echoed items
echo 'c';
// the final output should be equal to 'c', not 'abc'
?>
My script uses the include function. The included files are not supposed to echo anything. Just in case someone (ex = hacker) tries, I need a way to remove.
<?php
ob_start();
echo 'a';
print 'b';
// some statement that removes all printed/echoed items
ob_end_clean();
echo 'c';
// the final output is equal to 'c', not 'abc'
?>
Output buffering functions
The output buffering functions are also useful in hackery to coerce functions that only print to return strings, ie.
<?php
ob_start();
var_dump($myVar);
$data = ob_get_clean();
// do whatever with $data
?>
while #monoxide is right, its better to find more intuitive ways of doing the same. e.g.:
<?php
$val_to_print = $a;
if( $need_to_change==true )
$val_to_print = $b;
// when you are sure you won't have to change again...
echo $val_to_print;
?>
Cheers,
jrh
Ideally, you shouldn't output anything that you don't ultimately want printed. Keep your logic separate from your presentation for less frustration.
That being said, you can consult the Output Buffering options within PHP.
If it is debug output and program status information you are worried about maybe trigger_error may be nearer to what you need, such as:
trigger_error ("Attempting to load report #{$report_id}.", E_USER_NOTICE);
When your script is in production it wont show up any errors as generally they are disabled or logged. It's also best to do fatal errors this way with E_USER_ERROR rather than using die ().
ob_start ();
require ($filename);
$html = ob_get_clean ();
The above will also include a file and give you its contents as a string.
Caveat: Ditching the buffer will also ditch any error messages thrown up, making debugging (potentially) a nightmare.
If a hacker let's say has access to your PHP file, he will also be able to remove the statement clearing the output buffer.
If you are doing this because you are letting your users upload PHP scripts, let me tell you that this is an extremely bad idea.
In both cases, doing what you are asking for adds 0 security.

Categories