SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 41
  1. #1
    SitePoint Enthusiast
    Join Date
    May 2009
    Posts
    44
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    when to use ob_start() and ob_end_flush()

    Should I use ob_start() at the beginning of every script that uses header('Location: file.php') and ob_end_flush() at the end of that same script?

  2. #2
    @php.net Salathe's Avatar
    Join Date
    Dec 2004
    Location
    Edinburgh
    Posts
    1,396
    Mentioned
    54 Post(s)
    Tagged
    0 Thread(s)
    The necessity of using the output buffering functions depends on the individual script. The best practice, in general terms, is to separate processing code from code which issues output. Why would you want to send some output to the client and only later decide that it would be better to redirect them to another location — that in itself is a bad practice. Rather than wrapping up the code in output buffering (effectively putting a band aid over the problem) it's generally better to re-organise the code so as to not require the output buffering remedy.
    Salathe
    Software Developer and PHP Manual Author.

  3. #3
    SitePoint Enthusiast
    Join Date
    May 2009
    Posts
    44
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Several sources are telling me that, when redirecting to another page output buffering needs to be on. I'm asking when is the best position in the code to use ob_start() and ob_end_flush().

  4. #4
    @php.net Salathe's Avatar
    Join Date
    Dec 2004
    Location
    Edinburgh
    Posts
    1,396
    Mentioned
    54 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by sd3923 View Post
    Several sources are telling me that, when redirecting to another page output buffering needs to be on.
    Please don't believe those sources. There is absolutely no reason why output buffering needs to be used when redirecting.

    If you want to play it safe and not really learn anything useful from making this thread then put ob_start() as high up your script as possible, and ob_end_flush() as far down as possible.
    Salathe
    Software Developer and PHP Manual Author.

  5. #5
    SitePoint Enthusiast
    Join Date
    May 2009
    Posts
    44
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Salathe View Post
    If you want to play it safe and not really learn anything useful from making this thread then put ob_start() as high up your script as possible, and ob_end_flush() as far down as possible.
    You have an attitude problem. Not learn anything? You're giving me advice of exactly what you said not to do.

    If you're so concerned about me learning something you should have explained the points you want to get across.

    Please don't reply to anymore of my posts.

  6. #6
    @php.net Salathe's Avatar
    Join Date
    Dec 2004
    Location
    Edinburgh
    Posts
    1,396
    Mentioned
    54 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by sd3923 View Post
    You have an attitude problem.
    I wouldn't agree with that particular point, just to clarify, but you're absolutely entitled to read into my few words whatever notions you please.

    By stating that you shouldn't be doing what you want to do, I was aiming at guiding you along another train of thought; one which will be a far better practice for you to get into in the long run. You clearly were not interested in that so I gave you the simplest advice I could—what I thought you wanted to hear—even if it goes against what anyone else with any experience would say.

    Quote Originally Posted by sd3923 View Post
    If you're so concerned about me learning something you should have explained the points you want to get across.
    I was saving writing a few hundred words on why x is better than y and z (instead preferring a condensed approach at first) until such a time that it appeared you were receptive to reconsidering what you were asking. Why waste time going tangentially off-topic based on a one-line post?

    Quote Originally Posted by sd3923 View Post
    Please don't reply to anymore of my posts.
    Noted. It will not happen again unless directed to do so.
    Salathe
    Software Developer and PHP Manual Author.

  7. #7
    SitePoint Guru
    Join Date
    Aug 2009
    Posts
    669
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Salathe View Post
    I wouldn't agree with that particular point, just to clarify, but you're absolutely entitled to read into my few words whatever notions you please.
    In fairness what you have said is a bit contradictory. You've told him not to use that method and then in the next reply told him to do just that!

    I'm also in a similar situation.. I use output buffering in the main script of my program as the main script handles several different things. Now.. let me show you an example:

    script-a.php is the main php script.

    Now, it handles several things.. It can output a form, a results page and finally redirect a user to another url. Now.. how in advance is the script supposed to know if it should use output buffering or not?

    I'll appreciate that theoretically you could put all the scenarios in a switch() and then use output buffering in the appropriate case but if script-a.php also includes the use of a skin/template at the top.. you're stuffed because the headers have already been sent!

    Get my drift?

    For example, here is how my code works:
    Code:
    //script-a.php
    include('header.php');
    
    switch($_GET['mode'])
       {
       case "logon":
          //Log-on user and output page
          break;
       case "logoff":
          //Log-off user and output page
          break;
       default:
          //redirect..
          header('Location: other.html'); //ERROR!! - Headers already sent!
          break;
       }
    include('footer.php');
    Now, in that sample you're stuffed so YES output buffering would need to be used at the top and bottom for every part of the program. I appreciate you can break the entire program up into seperate scripts but we all have different ways of coding!

  8. #8
    @php.net Salathe's Avatar
    Join Date
    Dec 2004
    Location
    Edinburgh
    Posts
    1,396
    Mentioned
    54 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by tangoforce View Post
    For example, here is how my code works:
    It would make more sense, to me at least, to move things around a bit. Your scripts, in my opinion, would benefit from separating the decision-making logic from the behind-the-scenes actions and also the output. With your example code that might be structured something like:

    PHP Code:
    // 1. Decide what this page wants to do
    switch($_GET['mode'])
    {
       case 
    "logon":
       case 
    "logoff":
       break;
       default:
          
    //redirect and stop further processing
          
    header('Location: other.html');
          exit;
       break;
    }

    // 2. Do it (super-basic example)
    $view $_GET['mode'](); // logon() or logoff()

    // 3. Show pretty page
    include('header.php');
    echo 
    $view;
    include(
    'footer.php'); 
    With that sort of separation there's no bother over the possibility of getting output before all of the necessary headers have been sent.

    Off Topic:

    With regards to being contradictory, I guess the last paragraph of that post ("If you want to play it safe…") could have been prepended with "I wouldn't advise doing this but". I figured my view was already clear and didn't need that kind of clause added.
    Salathe
    Software Developer and PHP Manual Author.

  9. #9
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    I think Salathe has been the victim of misunderstandings here! His points are perfectly valid, and @OP, you need to sort your attitude out.

    You're posting on a forum where people give their own time to help others. To start off, you've been misinformed by people who (judging by what he said) spaghetti-codes and you shouldn't really trust what he says, and Salathe simply pointed out that those sources shouldn't be bothered with in a polite way and you reply by slating the guy who seems to make the most sense in this thread. You really need to think about that - the guy's trying to help.

    But basically, any code which affects the browser and the output of the page (e.g. could redirect the page, writes cookies, processes forms etc) should be done before anything at all is output - as Salathe pointed out.

    The only place I would think about using output buffering is when wanting to store the output of an include in a variable, for example:
    PHP Code:
    ob_start();
    include(
    'someView.php');
    $something ob_get_clean(); 
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  10. #10
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,600
    Mentioned
    24 Post(s)
    Tagged
    1 Thread(s)
    Using buffering and using redirects are two totally separate things. Your reasons for using buffering should not be dependent in any way on whether there are or are not any redirects within the code.

    While buffering bypasses the error you get if you have output something to the page and then tried to do a redirect, it isn't solving that problem, it is just hiding it. Buffering using ob_start() and ob_end_flush() are intended for a completely different purpose entirely.

    You should use each command for the purpose for which it is intended. If you don't know what buffering is really for then you shouldn't be using it.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  11. #11
    SitePoint Guru
    Join Date
    Aug 2009
    Posts
    669
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by felgall View Post
    While buffering bypasses the error you get if you have output something to the page and then tried to do a redirect, it isn't solving that problem, it is just hiding it. Buffering using ob_start() and ob_end_flush() are intended for a completely different purpose entirely.
    I do understand that and I do agree however sometimes due to the design logic of the code it's not always possible to do things in a 'perfect' way and so you need to find a hack around it. I think it's fair to say that regardless of whether buffering is used for its original purpose, if it gets the job done its good enough for most of us.

    Quote Originally Posted by felgall View Post
    You should use each command for the purpose for which it is intended. If you don't know what buffering is really for then you shouldn't be using it.
    As above, it doesn't really matter if it still achieves the desired results. I agree it's not the perfect way of doing things but the end result in my case was the same - the browser was redirected. Point made!

  12. #12
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by tangoforce View Post
    sometimes due to the design logic of the code it's not always possible to do things in a 'perfect' way and so you need to find a hack around it.
    I've never come across a situation where I have to output before I've done all the necessary processing (which may involve redirects).
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  13. #13
    SitePoint Guru
    Join Date
    Aug 2009
    Posts
    669
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have! - Learners!

    Learners should be encouraged gently and not told off, given a disciplining etc. Just gently explain where they've gone wrong and how it could be done better without contradiction. Code samples are always a winner with learners too instead of criticism no matter how mild it is.

    I'm still a learner myself.. but I've got a very good set of communication skills thanks to some tough jobs I've had in the past which needed me to talk my way out of some very hostile situations. I can break things up and explain them far better than some degree level programmers and all their hi-tech jargon talk. Sometimes experienced programmers without meaning to can sound offensive purely because they're so good at what they do that they forget that new people don't understand these so called 'little' issues and it can be intimidating to a new comer.

    I've had my fair share of arguments with some of the best programmers known - including TeamB programmers. Took a while to work out it wasn't them being narky, aggressive or rude, they just don't have the same people skills that others do or they can't break things down into simple terms to explain to learners. Remember learners are still practicing how to design their programs and logic processes. It's something we've all had to do and we've all had to learn to re-design things.

    Thats all it is.

    I'm certainly not slating salathes response but it was a bit contradictory and from a learners POV confusing. As mentioned above some code samples or even logic samples would of worked wonders here.

  14. #14
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,600
    Mentioned
    24 Post(s)
    Tagged
    1 Thread(s)
    Where you find that you have to redirect and you have already started to write output to the page you have a logic error in the way that your code is designed. It is fairly common for beginners who do not yet have much programming experience to have lots of logic errors in the code they are writing. You can't expect them to gain all the necessary programming skills to do things perfectly in five minutes.

    Where they have made a logic error and have asked more experienced programmers for help the correct solution is to explain how the code contains a logic error and how to rectify that particular error. Of course in order to do that you need to be able to see the actual code with the logic error in it in order to be able to explain exactly how to fix it.

    As sd3923 hasn't posted an example of their PHP code it isn't possible to describe exactly how to fix whatever page it is that has the issues. All that can be said is that buffering just hides the logic error without fixing it and until you fix the logic error there is always the potential for there to be other problems caused by the logic error that the patch doesn't hide. By all means post the actual code of any web page that contains a logic error like this so that more experienced programmers can assist you in fixing the logic error properly rather than just hiding it.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  15. #15
    SitePoint Zealot Kayarc's Avatar
    Join Date
    Sep 2009
    Posts
    127
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by felgall View Post
    Using buffering and using redirects are two totally separate things. Your reasons for using buffering should not be dependent in any way on whether there are or are not any redirects within the code.
    And this is about as best as you can put it.

    Also maybe I'm wrong but it seems that php.net is often bypassed as a source to learn from
    Phoenix Arizona Web Design | info *at* kayarc.com | 602.633.2676

  16. #16
    @php.net Salathe's Avatar
    Join Date
    Dec 2004
    Location
    Edinburgh
    Posts
    1,396
    Mentioned
    54 Post(s)
    Tagged
    0 Thread(s)
    Off Topic:


    Originally posted by Kayarc
    Also maybe I'm wrong but it seems that php.net is often bypassed as a source to learn from
    The PHP manual available online at php.net (with offline versions available) is a very good technical document, and much effort is made to make it accessible to all levels of PHP developer (from introducing the absolute basic of the language, through to in-depth technical documentation) there do appear to be some hurdles in the path of beginners wanting to make use of it.

    The various "book" sections go some way to helping, beyond the API documentation, but there is certainly still much scope for more teaching/tutorial style writing to encourage people to consider the manual as a place with information other than technical API docs. I've had a number of reports from people stating that the manual just goes way over their heads.

    On that note, if you or anyone has any ideas, thoughts or requests then do feel free to contact me personally (my username at Sitepoint @php.net) or use the bug reporting system to make the team aware of any problems, oversights, issues, etc..
    Salathe
    Software Developer and PHP Manual Author.

  17. #17
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,046
    Mentioned
    16 Post(s)
    Tagged
    3 Thread(s)
    Output buffering is very useful when you would like to support nested controllers/modules. If a module/controller can be executed from within a template/view buffering is a must. The best place to use output buffering is when you would like to embed on template inside another and inside another and inside another and so on. Where the inner most template may execute a module/controller that would change headers, cookies, etc.

    The below represents this simple scenario. Without output buffering '<p>master</p>' would be sent to output and the nested module Login would not be able to affect the state of cookies, headers, etc w/o error.

    PHP Code:
    <p>master</p>

    <?php echo $this->_objDriver->executeModule('Login'); ?>

  18. #18
    SitePoint Guru
    Join Date
    Aug 2009
    Posts
    669
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Kayarc View Post
    And this is about as best as you can put it.

    Also maybe I'm wrong but it seems that php.net is often bypassed as a source to learn from
    I'd also agree with that. I'm only a learner and I'm there on a daily basis but its frightening how many folks come here to ask even the most basic questions! Questions which are easily solved, understood and learned from by visiting php.net.

    My biggest trouble is remembering what parameters functions take and in what order... hence I'm a pretty regular visitor.

  19. #19
    Floridiot joebert's Avatar
    Join Date
    Mar 2004
    Location
    Kenneth City, FL
    Posts
    823
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by sd3923 View Post
    Should I use ob_start() at the beginning of every script that uses header('Location: file.php') and ob_end_flush() at the end of that same script?
    Simple answer, no. Not every script.

    If it's an existing script that you're modifying, you'll have to determine how that script works and see if there will ever be a case when either your additions will use the header function after the existing script has printed/echoed something, or if your addition will print/echo something before the existing script uses the header function.

    If the answer is yes to either situation, using ob_start() is a fix. Just like putting a plug in a flat tire is a fix. It works, it will work until you can get a new tire, but it's not as good as having the new tire. There's also the chance that it's a tear in the tire that could be mended back together using industrial adhesive, which again is a fix, but still not as good as a new tire.

    If it's a new script you're writing, then it's a matter of preference. Some people like to mix PHP and HTML like the following here.

    Code HTML4Strict:
    <div><?php echo $something; ?></div>

    It's not "wrong" per-say, but that style of coding sometimes forces you to use output buffering (what's actually provided by ob_start) if there is any chance of needing to send any HTTP Headers (not just "Location:") with the header() function later in the application.

    So if you're using that style of mixed PHP/HTML, then yes. You should probably use ob_start() at the beginning of "every script that uses header('Location..." like you asked. I stress probably though, because it could be argued that you should be able to determine whether any headers will be sent before outputting anything. In which case you wouldn't need to use the buffer.

    --

    If you're not the type to use the mixed PHP/HTML style, and your code generally looks more like the following

    Code PHP:
    <?php
    $template = new template('./html401.html');
    $template->load_file_into('./cache/popular.html', '<div id="popular"/>');
    echo $template;
    ?>

    Then chances are you're not going to need output buffering much, if at all. The application will generally have its' own output buffering logic built in, and have no need for the PHP output buffer.

    There are exceptions, occasionally you'll come across strange functions or code bases you're forced to work with that echo/print from within a function instead of returning the value. Sometimes you have to wrap that section up using the output buffering functions, but it's not going to require you to use ob_start at the beginning of every script.

  20. #20
    SitePoint Wizard lorenw's Avatar
    Join Date
    Feb 2005
    Location
    was rainy Oregon now sunny Florida
    Posts
    1,094
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    The only way that I can see a use for it is if you want to a meta refreh type redirect. you could echo out "Redirecting to ....." sleep, then header location.

    Other than that it makes no sense to start output if you are doing a header location redirect.

    My 2c
    What I lack in acuracy I make up for in misteaks

  21. #21
    SitePoint Guru
    Join Date
    Aug 2009
    Posts
    669
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Like your style Joe

  22. #22
    Web Professional
    Join Date
    Oct 2008
    Location
    London
    Posts
    862
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Off Topic:


    Salathe. I always like your insightful input. Too bad it's unappreciated this time

  23. #23
    SitePoint Guru
    Join Date
    Aug 2009
    Posts
    669
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Before this turns into a flame war I'd like to state for the record that I've not said I dislike salathes comments. All I said was that in fairness it was a bit contradictory. Nothing more, nothing less.

    The reason I complimented Joe was because it was straight forward encouraging advice.

  24. #24
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,600
    Mentioned
    24 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by joebert View Post
    If it's a new script you're writing, then it's a matter of preference.
    Not really. Neither of the two programming styles you mention require buffering unless you have an error in your logic.

    oddz mentioned one instance where you would legitimately use buffering - the use of buffering is only needed where you have that level of complexity in the overall system.

    A beginner to PHP is a long way from even thinking about using the sort of constructs where buffering is required. Beginners are best off to forget that buffering even exists until they have gained a lot of experience of writing PHP without it since the sort of pages a beginner writes never need buffering if written correctly.

    Those who use buffering by preference are potentially hiding lots of logic errors in their processing which could be easily found and fixed if they were not hiding them.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  25. #25
    SitePoint Guru tictike's Avatar
    Join Date
    Apr 2008
    Location
    Canada
    Posts
    863
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I was going to ask a similar question, then I saw this thread was on top. I am a beginner, and I am using a redirect after output, however, I am getting an error, as expected . So here is the code (minfied to only include the necessary parts for this demo). Please point out the logic error.

    Code PHP:
    <?php require_once('functions.php'); ?>
    <!DOCTYPE HTML PUBIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    	<head>
    		<!-- head markup -->		
    	</head>
    	<body>
    		<div id="header">
    			<div>
    			<?php
    				if($foo == $bar){
    					// do something
    				}
    				else{
    					header('Location: index.php');					
    				}
    			?>
    			</div>
    .
    .
    .
    .

    Again, I'm a beginner, but the logic looks just fine to me. I pull in a functions file, and based on a simple if statement the page redirects.

    I understand that php doesn't want to redirect after it has already started output....but I don't get why I have a logic error.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •