Jump to content

Question about ob_start() and ob_flush() in regards to header() work around.


Recommended Posts

Recently I finally found a solution to a problem I had using header(), that was not due to white space issues like is normally the issue.  Someone had posted using ob_start() and ob_flush() at the tops and bottom of all my pages and amazingly this worked.  Unfortunately this person didn't give any detailed info or reasoning why this fixes the issue.  I hate using something just because it works I need more info.  Can anyone provide me info with what is going on with these 2 functions?  This isn't some kind of hacky way to make things work that can cause other issues later on is it?  Also since my site is basically included all into the main index.php why does this code need to go into every file?  Seems to me if it is in the main index.php file is should encapsulate the rest of the site, would it not?

The reason it works is because it saves all of the content you output in a output buffer. ob_start means "save all echos, print_rs, etc in a string (output buffer) instead of outputting it to the browser" and ob_flush or ob_end_flush outputs all of the content in the buffer to the browser. It's not really a FIX to the header() issue, it's more of a hack job, but it works.

ob_start() is to turn on output buffering

when the php process, whever it meet echo, it just save all the data into memory (or a temperary file, i am not sure) instead just send to the user on that line of code

 

 

Header() when every internet request, the server will send an header to the client, telling all the information that the browers will send, like what kind of file, and stuff, as it said, header, it must be send to the client first, before anything.

 

 

ob_flush() is to flush (send) all buffered data, send all the buffered data (those stored in memory) to the user

 

 

 

why it fix the header in the middle:

because you didnt send anything to the client yet, and header wont be buffered, and it is send once the php engine meet this line.

If you put those two functions at the start and end of your main index.php file (or at least before and after where a file being included generates a header() error) and it did not help with a header() error, then you are probably including the content using a URL instead of a file system path and this will make your site take longer to load because of the extra http requests.

 

It is always best to find and fix the cause of a problem. In this case, you got something to work but it appears that you are just masking a bigger problem within your code.

 

What does your include statements look like?

If you put those two functions at the start and end of your main index.php file (or at least before and after where a file being included generates a header() error) and it did not help with a header() error, then you are probably including the content using a URL instead of a file system path and this will make your site take longer to load because of the extra http requests.

 

It is always best to find and fix the cause of a problem. In this case, you got something to work but it appears that you are just masking a bigger problem within your code.

 

What does your include statements look like?

 

This is my index.php file.    If it is an echo problem what would you use in place of an echo command?

 

<? ob_start(); ?>
<?php 

session_start();

include 'html_functions.php';
include 'db/hhp_db.php';
include 'login_functions.php';
include 'registration.php';
include 'gameinfo_display.php';
include 'laninfo_display.php';

html_header();
menu();
main_page();		
html_footer();

?>
<? ob_flush(); ?>

That piece of code shows us nothing.

 

The simple point is this. Why echo data (or send any data) to the browser if all you are going to do is redirect the user to another page? It makes absolutely no sense.

 

Organize you code in such a way so as that it only sends a response when it is needed.

Actually it shows that you got caught by using lazy-way short open tags in your code. Short open tags are NOT always enabled on any particular server and you won't always be on a server where you will have the ability to turn them on. Short open tags should not be used at all. Why, when you have full opening php tags in the rest of the posted code did you then put in some code using short open tags? Be consistent.

 

Then find and correct what ever is causing output on your page that is occurring before a header() statement or rearrange your code to put the header() before the output.

Actually it shows that you got caught by using lazy-way short open tags in your code. Short open tags are NOT always enabled on any particular server and you won't always be on a server where you will have the ability to turn them on. Short open tags should not be used at all. Why, when you have full opening php tags in the rest of the posted code did you then put in some code using short open tags? Be consistent.

 

Then find and correct what ever is causing output on your page that is occurring before a header() statement or rearrange your code to put the header() before the output.

 

I don't follow what you are saying.  I just threw in <? ob_start(); ?> like that real quick for testing purposes so that if it didn't work I would just delete it out quick. 

I believe what PFMaBiSmAd was saying is that if you wanted to test ob_start() you should really have put..

 

<?php ob_start(); ?>

 

Since putting <? obstart(); ?> is taking a gamble on the settings in your php.ini (assuming you don't explicitly know that you have short_tags enabled).

I believe what PFMaBiSmAd was saying is that if you wanted to test ob_start() you should really have put..

 

<?php ob_start(); ?>

 

Since putting <? obstart(); ?> is taking a gamble on the settings in your php.ini (assuming you don't explicitly know that you have short_tags enabled).

 

Ok lets get of this short tag trip as I said before I only used them to add that code quick and dirty like.  Since my web page works prefectly with them i am sure they are a none issue anyways. 

Ok I took out all the short tags and ob_start() and ob_flush() and this is the line of code it is choking on.  Line 17 which is <div id="pagelayout"> .

 

 

<?php 

function html_header(){
?>
	<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
	<html>
	<title>Hukai's House of Pain</title>
	<head>
		<link rel="shortcut icon" href="images/skull.gif">
		<link rel="stylesheet" href="styles/hhp.css">
	</head>
	<body spacing="0">
	<DIV id="headertitle">HUKAI'S HOUSE OF PAIN</DIV>
	<DIV id="headerlandate">Next LAN Party Jaunuary 17, 2008</DIV>
	<DIV id="headerfragtimer"></DIV>

	<div id="pagelayout">
	<div id="pagelayoutmenu">
	<div id="sidemenu">
<?php
}

choking on?

After the header() is called the site errors out with this error message.

 

Warning: Cannot modify header information - headers already sent by (output started at /home/content/b/o/c/bocci572/html/lanparty/beta/html_functions.php:17) in /home/content/b/o/c/bocci572/html/lanparty/beta/login_functions.php on line 29

What has the information you just posted got to do with the post you made previous to it? It says an error has occured because of login_functions.php on line 29, in what way is that Line 17 of the main page?

 

Anyway. With the fact that the error is being caused by login_functions.php, I'm assuming that is the location of the header() function call.

 

Looking at the top of your code you have the following.

 

<?php 

session_start();

include 'html_functions.php';
include 'db/hhp_db.php';
include 'login_functions.php';

 

Assuming my previous statement is true and the header call is on (or around) line 29 of 'login_functions.php', then we can (fairly) safely assume that either there is output in the file above the line

 

include 'login_functions.php';

 

I'd personally automatically discount this file since session_start() must be before headers, it's safe to say there's no whitespace above the code block. Therefore you have output in either 'html_function.php', 'db/hhp_db.php' or before line 29 in 'login_functions'php'.

 

Since the naming of these files seems to indicate they are just containers for functions, I'd personally guess that at the top of one of those files there is whitespace characters before the <?php tag.

What has the information you just posted got to do with the post you made previous to it? It says an error has occured because of login_functions.php on line 29, in what way is that Line 17 of the main page?

 

Anyway. With the fact that the error is being caused by login_functions.php, I'm assuming that is the location of the header() function call.

 

Looking at the top of your code you have the following.

 

<?php 

session_start();

include 'html_functions.php';
include 'db/hhp_db.php';
include 'login_functions.php';

 

Assuming my previous statement is true and the header call is on (or around) line 29 of 'login_functions.php', then we can (fairly) safely assume that either there is output in the file above the line

 

include 'login_functions.php';

 

I'd personally automatically discount this file since session_start() must be before headers, it's safe to say there's no whitespace above the code block. Therefore you have output in either 'html_function.php', 'db/hhp_db.php' or before line 29 in 'login_functions'php'.

 

Since the naming of these files seems to indicate they are just containers for functions, I'd personally guess that at the top of one of those files there is whitespace characters before the <?php tag.

 

Ok we are getting somewhere now!  Pretty much everything you said you have right.

 

include 'html_functions.php';  This is just function calls for html headers and footers and such.

 

include 'db/hhp_db.php';  This is just connection to the database.

 

include 'login_functions.php';  The first part of this code I will post below and yes line 29 is the header().

 

<?php

function checkuser(){ 

$username = $_POST['username'];
$password = $_POST['password'];

if((!$username) || (!$password)){
	echo "Please fill in both fields! <br />";
	login_form_display();
	exit();
}

$username = stripslashes($username);
$password = stripslashes($password);

$password = md5($password);

$sql = mysql_query("SELECT * FROM tbl_user_access WHERE fld_login_id='$username' AND fld_password='$password'");
$login_check = mysql_num_rows($sql);
$row = mysql_fetch_array($sql);
$user_id = $row['fld_user_id'];

if($login_check > 0){
	$_SESSION['fld_user_id'] = $user_id;

	$sql2 = mysql_query("UPDATE tbl_user_access SET fld_last_login= now() WHERE fld_user_id='$user_id'") or die (mysql_error());

	header("Location: index.php"); 
} else {
	echo "You could not be logged in! Either the username and password do not match or you have not validated your membership!<br />
	Please try again!<br />";
	login_form_display();
}		
}

Ok, looking at that code, there is output, but nothing in the same 'code path' as the header. What I mean is whilst you call echo, if that is ever called your code can never reach header() so thats not causing the problem. Therefore the problem is with either 'html_functions.php' or db/hhp_db.php'.

 

The way I'd personally look for the problem is to place die("HERE"); on the line before you call header(). Then in your browser click 'View Source'. You should find that HERE is not the first thing in the source. If there are characters simply search the two files for anywhere that has those characters. If there are no visible characters, the changes are HERE will not be on the first line, that means that one of your <?php tags is not the first thing in one of the files.

 

Your <?php tag is valid

HERE

 

Your <?php tag is invalid (in terms of using header)


HERE

Ok, looking at that code, there is output, but nothing in the same 'code path' as the header. What I mean is whilst you call echo, if that is ever called your code can never reach header() so thats not causing the problem. Therefore the problem is with either 'html_functions.php' or db/hhp_db.php'.

 

The way I'd personally look for the problem is to place die("HERE"); on the line before you call header(). Then in your browser click 'View Source'. You should find that HERE is not the first thing in the source. If there are characters simply search the two files for anywhere that has those characters. If there are no visible characters, the changes are HERE will not be on the first line, that means that one of your <?php tags is not the first thing in one of the files.

 

Your <?php tag is valid

HERE

 

Your <?php tag is invalid (in terms of using header)


HERE

 

Well when I do that I see all the HTML header info up to the point where php takes over from there.  This would be the code that would be executed next.

 

function main_page(){
if ( $_GET['page'] == null ) {
	$menu_link = welcome_page;
	$menu_link();
}else{		
	$menu_link = $_GET['page'];
	$menu_link();
}

}

 

That code gets values from this menu.

 

<ul>
					<li><a Href="?page=welcome_page">Home</a></li>
					<li><a Href="?page=laninfo_display">Lan Party Info</a></li>
					<li><a Href="?page=gameiso_display">Game ISO</a></li>
					<li><a Href="?page=appz_display">Appz/KeyGen</a></li>
					<li><a Href="?page=cdkeys_display">CD Keys</a></li>						
					<li><a Href="?page=patch_display">Patches</a></li>
					<li><a Href="?page=cracks_display">Cracks</a></li>
					<li><a Href="?page=driver_display">Drivers</a></li>
					<li><a Href="?page=logout">Logout</a></li>
				</ul>

 

*sigh* I feel like I'm stuck in a recursive loop here. The header function can only be used before output is made, if you can see all the HTML header info, then of course your getting an error.

 

I guess I should put my hand up to the fact I failed to notice that the actual code where header is called is in a function, which changes things, because the output is occuring before that function is called, not before the file is included. I have no idea where in your code this might be.

 

Let me put it in the simplest terms I can think of...

 

The function checkuser() must be called before any other code that will output. Without seeing all your code it's impossible for us to know exactly where that would be. I wouldn't even like to hazard a guess where that might be, if I was forced to, my best guess would be....

 

<?php 

session_start();

include 'html_functions.php';
include 'db/hhp_db.php';
include 'login_functions.php';
include 'registration.php';
include 'gameinfo_display.php';
include 'laninfo_display.php';
   // HERE
   checkuser();
   // ^THERE
   html_header();
   menu();
   main_page();      
   html_footer();
   
?>

 

... but for all I know you have output in your include files.

 

Incidently if your server has short_tags enabled as you say, then...

 

<? ob_start(); ?>
<?php 

session_start();

include 'html_functions.php';
include 'db/hhp_db.php';
include 'login_functions.php';
include 'registration.php';
include 'gameinfo_display.php';
include 'laninfo_display.php';
   
   html_header();
   menu();
   main_page();      
   html_footer();
   
?>
<? ob_flush(); ?>

 

... should have worked. Did you actually try...

 

<?php 
ob_start(); 
session_start();

include 'html_functions.php';
include 'db/hhp_db.php';
include 'login_functions.php';
include 'registration.php';
include 'gameinfo_display.php';
include 'laninfo_display.php';
   
   html_header();
   menu();
   main_page();      
   html_footer();
ob_flush();   
?>

The Short tag version with ob_start() does work but if ob_start() is a hacky way of doing it I prefer to learn how to do it the right way.

 

 

How about we look at this problem from another perspective?  Since basically I am using the header() to refresh the page.  How else could I go about this?  If i can't put the header() into a function how else would you make the page refresh?

I think the problem is that your approach is... I'm not sure of the right word, I'm trying to avoid using the word wrong, so lets just say 'not the most logical'. I can't personally think of a valid reason to refresh a page halfway through drawing it, it doesn't make any sense.

 

I'm going to speculate that your doing it to cope with error messages, or some kind of user feedback. If thats the case then your page should be layed out more like so.

 

<?php
start_session();
// include require files that contain functions here, but NO OUTPUT (unless it's inside a function, thats fine)

// perform any logic required for the page
// any feedback we STORE for later use 
// very basic, example
if($_POST['username'] != "JOHN") {
  $error = "Invalid username";
}

// start output of files
output_header();

// rest of page goes here, including anything calculated earlier
if(!empty($error)) { echo $error; }

// end page
output_footer();

// voila
?>

 

In reply to your last message, yes, that is output. Output is any line of code that creates something that will appear when you click 'View source' in a brower. In other words, it's anything outside of <?php ?> tags, or anything output by echo, print, print_r or any of the other functions that create output.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.