sehummel
sehummel

Reputation: 5568

PHP header and output buffering not working

I'm confused about how output buffering works with the PHP header function.

Here is my code:

session_start();

header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');

require_once ($_SERVER['DOCUMENT_ROOT'] . '/classes/database.php');
require_once ($_SERVER['DOCUMENT_ROOT'] . '/classes/functions.php');

$db = new Database();
$db->open_connection(); // to database
$query = 'SELECT * FROM english WHERE id = ' . mysql_real_escape_string($_GET['dealerID']);
$result = mysql_query($query) or die(mysql_error());
$row = mysql_fetch_array($result);
ob_start();
ob_flush();
header('http://www.domain.com/channel-partners/en/index.php?dealerID=' . $row['id'] . '&location=' . $row['location_url'] . '&name=' . $row['name_url']);   
ob_end_flush();

This doesn't work. I get the "headers already sent" error. I know that I can't have any output before I call the header command, but I thought if I used ob_start() I could have output before the command is called. Obviously I am mistaken, but I don't know how to rectify this code so that I can have the session_start() where it needs to be, open a connection to my database and then call the redirect. Can someone help out? Thanks.

Upvotes: 2

Views: 2405

Answers (4)

Michael
Michael

Reputation: 35341

Remove the call to ob_flush(). This sends output to the response and prevents you from setting any more headers.

Also, you should encode your query string parameters:

header('http://www.domain.com/channel-partners/en/index.php?dealerID=' . urlencode($row['id']) . '&location=' . urlencode($row['location_url']) . '&name=' . urlencode($row['name_url']));

Or better yet, use the http_build_query() function:

$params = array("dealerID"=>$row['id'], "location"=>row['location_url'], "name"=>$row['name_url']);
header('http://www.domain.com/channel-partners/en/index.php?' . http_build_query($params));

EDIT:

One more thing. You're not escaping the dealerID properly in your query string. The mysql_real_escape_string() function is only useful for SQL strings. It is not useful for numeric values. Use the ctype_digit() function to check to make sure that the dealerID parameter is a number:

$dealerID = $_GET['dealerID'];
if (!ctype_digit($dealerID)){
  die('Invalid value for "dealerID" parameter.');
}

Upvotes: 5

Dan
Dan

Reputation: 2093

Try to put ob_start(); right at the top of your script.

Upvotes: 0

James C
James C

Reputation: 14149

You can find out where the headers were sent with:

if (headers_sent($file, $line)) { 
   echo "Headers were sent at file=$file, line=$line";
}

This should allow you to debug the problem

Upvotes: 0

ceejayoz
ceejayoz

Reputation: 180004

I know that I can't have any output before I call the header command, but I thought if I used ob_start() I could have output before the command is called.

You can, but you're calling ob_flush() prior to your header call, which sends output to the browser. Why? Take out the ob_flush() call and it should work exactly as intended.

Upvotes: 0

Related Questions