This question already has answers here:
PHP output buffering - sounds like a bad idea, is it?
(4 answers)
Closed 9 months ago.
I have read on many websites that using
ob_start();
can enhance your page load times, as it stores the php in a variable and displays it in one go rather than processing the php a bit of a time.
Also it is extremely useful for
header('location: /');
Some people say that this is spaghetti code, but as long as the code is clear and concise to any programmer then this should not be a problem, right?
What are your thoughts to using it, and what do you set as your output buffering, are there pros and cons to how, when and why I should or shouldn't use it.
The main advantage of output buffering is that you can use it with the ob_gzhandler which will compress your output so you use less bandwidth. Good to use if your server is not setup to send php files compressed.
Another advantage is if your script uses a database or other constrained resources and you have some output before closing your connections or releasing those resources. Instead of having this kind of thing:
Connect to database
Start sending output to the user
Wait for the user to receive everything
Close the database connection
You have:
Start buffering
Connect to database
Output some things
Close database connection
Send the buffer to the user.
When your script would need to be connected for 100ms to the database and your user need 300 more to download it, you can understand how output buffering can help releasing some stress on the database connections limit.
I know something coded well using a well configured server could nullify those advantages, but you never know who will code after you and you don't always have control of the server it's running on.
some user dont know php well. so they use ob_start wrongly.
if you are using header functions such as header(), cookie(), session you dont have to send any output. these function have to use from before output.
but some user is to stop sending output using ob_start or output buffering function.
so you could use javascript or meta forwading to forward user.
<script language="javascript"> window.location = 'some.php'; </script>
or you could use meta refresh to forward user.
<META HTTP-EQUIV="Refresh" CONTENT="0;URL=some.php">
if you really need to use header function you must dont send any output(dont forget that enter character or space is or UTF-8 signature is output too)
Related
I have set things up so my code reads the text of each page and automatically generates a table of contents and list of footnotes from it. I put footnote text into the page text in the place that it refers to. When the code reads the page file, it constructs a table of contents from the headers and puts that at the beginning of the page. It also removes the text of the footnotes and puts them in a list that it puts at the end of the page. It also manages numbering of the footnotes and placement of linked, superscripted footnote numbers for them.
To do this, instead of echo()ing page content, I compile the content into a variable, $PageText. I then have functions that read that variable, remove the footnote text, compile the table of contents and list of footnotes, and insert those into $PageText. I then echo($PageText);.
It seems that what I'm doing here is a homemade form of buffering, and that I could accomplish the same thing by something like
ob_start();
echo(<page contents>);
$PageText = ob_get_contents();
make_ToC($PageText);
make_footnotes($PageText);
ob_end_flush();
Would that be more efficient that using my own buffer variable? Or is there any other reason that it would better to use the built-in buffering system?
The reason I prefer to use my own buffer is that I have complete control of it. I don't really know what PHP might decide to do with content between the time that I echo() it and the time that I flush it.
A similar question was asked five years ago, Output buffering vs. storing content into variable in PHP. It's interesting that the answers seem to say that I would have better control of the contents by using the "ob_" system, whereas I feel like I have better control by using my own variable. Is there something I don't understand about that?
Output buffering is a technique to put already generated output on hold and has a number of usages:
Make better use of network transmissions (e.g. avoid sending almost empty HTTP packages)
Apply transparent transformations (e.g. minify generated HTML or rewrite URLs)
Being able to cancel the output altogether (e.g. in case of error)
Capture the output of functions that print to stdout (e.g. var_dump())
In my experience, functions that print to stdout tend to be an annoyance, esp. if the only apparent reason to do so is not having to prepend echo, because they get in the way of your application design. You don't always want to send their output as-is and you don't always want to print the output in the exact spot of the response flow where the function call happens.
What you describe is basically the standard text manipulation you can expect in any program. While you can certainly emulate it with output buffering, and as opinionated as it can get, I think it feels like a hack. In your case, you aren't even doing linear output. There's no obvious benefit of printing to stdout at once, given that you still need to manipulate the output because it isn't ready yet.
Using an output buffer requires the server to store the entire output of the PHP in RAM, so if I have a large page, I'll wind up using a fair amount of memory - and the server will also have to wait until the entire page is generated before sending it out, which could cause a small delay. that's right ?
I don't want to know the advantage of using ob_start();. My problem is redirecting and this error: Headers already sent.
So for solving that problem, I used of ob_start(); in the fist of my codes. something like this:
<?php ob_start(); ?>
<?php
// 500 lines of code is here
header(Location: www.example.com/test.php);
?>
<html>
// 1000 lines of code is here
</html>
<?php ob_end_flush(); ?>
Now my problem has been solved, just I want to know everything is ok ? my codes are optimized ? If my requests rise, my site does not delay ?
thanks
The proper solution to the "Headers already sent" problem is described in a previous thread.
Basically, the correct cause of action is to move all of the processing code above any output to the browser. Then simply echo out the results, as needed, in between the HTML code.
Not only will you notice an improvement in the resource usage of the page, but you'll also notice that it will become a whole lot easier to actually read and write the code.
If the output branches are complex enough, which means anything above a very basic script (simple guestbook, etc), a template engine might be well worth the time and effort to look at.
Output buffering is frequently used and I wouldn't worry about this. For example, this SO webpage takes up ~ 64 KiB, meaning 16384 of these pages fit in 1 GiB ram simultaneously.
Probably offtopic, but if you're going to send a Location header, do you even need to execute all the other code? You could just send the header and exit() immediately.
I am creating some kind of custom CMS (home automation).
Well I am not a PHP developer - just hobbyist.
What I am trying to achieve is:
In my index.php page I have something like:
"<?php echo $pageBody; ?> "
PageBody I am fetching from Database, well it works well for HTML, JS. But it doesn't work with PHP code source.
I done some research I believe this is related to PHP security restrictions.
My question: Does anybody would be able to provide safe sample (cannot find any samples like this) - how I should do this.
I am trying to insert some php code and render it eventually via browser:
<div id="outer">
<div id="inner">
***PHP Code should go here***
</div>
</div>
At the minute - it is being rendered as text. However I can render properly HTML and JS.
My preferable way would be - as much as possible secure.
Many Thanks Guys!
When you retrieve PHP code from a database text field, the PHP interpreter does not "know" that it should parse the data as a PHP script. To the PHP interpreter, the data in that field is no different from any other data -- it is all strings without any special significance.
You could use eval (docs) to accomplish this if you're dealing with pure PHP scripts. Be forewarned: eval is considered "evil" because using it comes with risks, especially if your users will have any input as to the content of the database.
In your case, it sounds like you want to parse mixed PHP and HTML that is stored in a database field. In order to do this, you'd need to write the database data into a file, then include it so the PHP interpreter can do its thing. You should implement some kind of caching mechanism in this process, otherwise it might become heavy on your server with many users. You may also want to use output buffering (docs) to capture the output instead of immediately sending it out.
Briefly, you'd want to do something like this:
$content_from_db = "<h1>Hello <?php print 'Clarisse'; ?></h1>";
$identifier_from_db = '12'; // like the primary key from the table
$file_handle = fopen('cached_content/CACHE_'.$identifier_from_db.'.php', 'w');
fwrite($file_handle, $content_from_db);
fclose($file_handle);
// here is where you'd start output buffering, if you're going to do that (optional)
include('cached_content/CACHE_'.$identifier_from_db.'.php');
// and then here you retrieve the output buffer's content (optional)
Please note that this is not a "traditional" way of including dynamic content, and the above code is not production-ready. Without knowing your use case, I can't say for certain, but this idea of storing PHP code in the database is a rather unusual way to proceed.
Another alternative to rolling your own is the smarty template library. Check it out here: http://www.smarty.net. With smarty, you can write a resource plugin to pull the templates from the database. It would look something like the code above (more info)
Documentation
fwrite - http://php.net/manual/en/function.fwrite.php
include - http://php.net/manual/en/function.include.php
PHP basics on theopensourcery.com - http://theopensourcery.com/phpbasics.htm
Server-side scripting on Wikipedia - http://en.wikipedia.org/wiki/Server-side_scripting
eval - http://php.net/manual/en/function.eval.php
Output Control (buffering) - http://php.net/manual/en/book.outcontrol.php
Smarty - http://www.smarty.net
to execute PHP that you store in a string (or database) you can use the eval function, but be careful it could be somewhat dangerous.
You can't render (probably you mean execute) php code in the browser, because php scripts execute on the server and then the output is sent to the browser. By the time the browser recieve the response, script has already finished execution.
You can fetch the code from database and use eval() before sending the output. But you must be aware of drawbacks from this approach.
Browser cannot render (execute) PHP code. PHP is something that the server executes and sends to the browser as plain HTML to display.
For testing purposes you can download and install WAMP thats the most hassle free one stop solution for development.
link : http://www.wampserver.com/en/
I have this:
echo "<font color=\"#000000\">text</font>";
usleep(2000000);
header("location:/otherpage.php");
?>`
Please note that this will be included in an iframe...
The problem is that it isn't echoing the echo statement, but then sleeping for two seconds and then redirecting (which is all correct except for the echo part)...
Anyone have an idea why this is happening?? It's not the iframe because when you go straight to the file (separately from the iframe) the same happens. Could it be the usleep??
Thanks
What you are doing above will not work. First, you would need to do a flush in order to make sure the data was sent. Second, though, and more important, you can't change the header after the flush, which would result in either the header not being sent or the text not being sent.
If all you want to do is change the data after a delay, did you consider doing the following:
header('Refresh: 2; url=http://my.site.com/otherpage.php);
echo "<font color=\"#000000\">text</font>";
This will send the information in the browser, instructing the browser to change to the new URL after 2 seconds.
This won't work since you can't change the header after outputting text.
The only option is to use a meta refresh or javascript when you want to exact replicate this behaviour.
But the output problem you can solve by flushing the buffer but then no redirection is possible as i mentioned before.
Another very important thing is:
DONT USE USLEEP FOR SUCH THINGS.
Why? Because when your script is heavily loaded every request which needs too much time is very bad and you will run out of php threads (depending on your php webserver implementation). So, for such timeouts you should use clientside code (if possible).
It's sleeping while on the server, and then sending the output. Also you can't send headers after echoing something.
You should use javascript or a meta redirect, this will allow you to wait a few seconds before redirecting, and the time and url for both of those can be generated by your php script.
You can't to that. I have a feeling you're misunderstanding the purpose of PHP and it's role as a server-side language.
If you want to "redirect" to another page in PHP, you do so using HTTP headers, which you did. The thing is, those are the headers, so they must be sent before any text body (like an echo statement). You're trying to do something that should be done client-side on the server.
Instead, make an HTML page with some JavaScript code to do the redirection, like that:
<script>
setTimeout(function() {
window.location = "otherpage.html";
}, 2000);
</script>
Expanding my comment into an answer:
It's not possible to redirect like this (outputting some content and then trying to send in a header) because headers must be sent before all content. PHP will also complain about this, using default settings you should see a warning.
Second, the usleep delay might not be observable due to the server buffering the content throughout the sleep and only sending it in one big chunk afterwards. In general, it isn't reliable to make the browser display content "in steps" like this, although it can be made to work more or less if you pile the hacks high enough.
May I suggest that if this kind of behavior is what you need, you should look into making a (series of?) appropriate AJAX call, which can be orchestrated perfectly.
What everyone else said. Just adding that usleep() will make clients hold connections open on your server---it's a very inefficient use of limited server resources. Your PHP should always send everything it can as quickly as possible so your web server can close the connection.
I'm writing an application that would allow users to edit a calendar, its description and a few other things. I'm using jquery, php and mysql. Each time the user makes a change it asynchronously updates the database.
I'd like to give them the option of turning what they make into a pdf. Is there a way that I can post to my server the raw html of the page after the user makes changes?
I could regenerate the page using only php on the server, but this way would be easier if possible.
You can use this to get most of the HTML for the page:
var htmlSource = document.getElementsByTagName('html')[0].innerHTML;
However it'll lack the opening and closing HTML tags and doctype, which probably won't matter to you as you could recreate that very easily back on the server.
I'll assume you can just use the same AJAX you're already using to send htmlSource to the server once you've grabbed it.
You can certainly return the innerHTML from jQuery any object that you can select, although it doesn't seem like the best way to go (see other answers for alternatives).
Watch out for XSS attacks. If you just run the HTML back and forth without checking it first you are leaving yourself open to major risks.
Regenerating the page from the server is going to be your best bet. To have a good downloading experience, you'll want to be able to send headers for Content-Type and size.
To answer your question, I would use output buffering to capture the output of your scripts, and then use one of the many tools available for turning HTML to PDF.