How to clear previously echoed items in PHP - 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.

Related

Shall I use output buffering (ob_start) or not

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!

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?

PHP Output buffering contains something before script starts

i have a site, where i buffer some output with
ob_start();
...
and it worked fine until today i updated my debian from an older php5.3 to the latest php5.3.3-7+squeeze8
Now i sometimes have something in the output buffer before i call it the first time
please don't answer things like
"header must be called before any output is sent."
(I know, I work a lot with output buffers)
when i set an extra ob_get_clean(); at the very first line of my script, it works
<?
ob_get_clean();
it seems, like php is creating some output beforehand
if i put the first line
<? print_r(ob_get_clean()); ?>
then i see, that there is an empty string already in the buffer:
""
on all other pages it isn't, there ob_get_clean(); contains
null
is it possible you have some " " in front of your <?php somewhere? or wrong file encoding issue its usually some kind of that nature, check your files and include files.
Now i sometimes have something in the output buffer before i call it
the first time
It'll be much easier if you give us some info about that mysterious data.
perhaps a case of BOM character?
more info here
i found it:
i had no invisible character in front, it was something different: i called ob_end_clean() one time too much:
this was my code, inside a function i call:
function print_something(){
ob_start();
echo some stuff...
echo ob_get_clean();
ob_end_clean(); // this was the bug!
}
it seems, that you can clear your main output buffer ;)

Using include() within ob_start()

Need a bit of PHP help here, the included content is appearing as '1' which means that its true but need it's contents to appear and im unsure why it isn't. Here is a shortened version of a function:
public function content {
$website->content = 'Some content here. ';
ob_start();
include('myfile.php');
$file_content = ob_end_clean();
$website->content .= $file_content;
$website->content .= ' Some more content here.';
echo $website->content;
}
This outputs:
Some content here
1
Some more content here
When I need it to output:
Some content here
'Included file content here'
Some more content here
Any idea's how I can fix this?
Try using ob_get_clean() instead of ob_end_clean().
Both clear the current buffer but ob_end_clean() returns a boolean, whereas ob_get_clean() returns the contents of the current buffer.
Instead of using ob_end_clean modify your existing code into something similar to the below
ob_start();
include('myfile.php');
$file_content = ob_get_contents();
ob_end_clean ();
The reason I'm not voting for ob_get_clean is because I've had times when other developers get confused regarding what is really going on, the function name doesn't really state that the output buffering will end after it's call.
I think that function will be prone to further bugs, therefor using ob_start/ob_end_clean is easier to comprehend and better for future code maintenance.
The trade off between one extra line of code but easier code to understand is well worth it.
You should be using ob_get_clean(), not ob_end_clean(). The former returns a string of the output buffer and empties it, while the latter just does the emptying and returns a bool.

How do I capture the result of an echo() into a variable in PHP?

I'm using a PHP library that echoes a result rather than returns it. Is there an easy way to capture the output from echo/print and store it in a variable? (Other text has already been output, and output buffering is not being used.)
You could use output buffering :
ob_start();
function test ($var) {
echo $var;
}
test("hello");
$content = ob_get_clean();
var_dump($content); // string(5) "hello"
But it's not a clean and fun syntax to use. It may be a good idea to find a better library...
The only way I know.
ob_start();
echo "Some String";
$var = ob_get_clean();
You should really rewrite the class if you can. I doubt it would be that hard to find the echo/print statements and replace them with $output .=. Using ob_xxx does take resources.
Its always good practise not to echo data until your application as fully completed, for example
<?php
echo 'Start';
session_start();
?>
now session_start along with another string of functions would not work as there's already been data outputted as the response, but by doing the following:
<?php
$output = 'Start';
session_start();
echo $output;
?>
This would work and its less error prone, but if its a must that you need to capture output then you would do:
ob_start();
//Whatever you want here
$data = ob_get_contents();
//Then we clean out that buffer with:
ob_end_clean();

Categories