Database Driven, Kevin Yank 4th Ed., P.139

Hi, from Build Your Own Database Driven Site, 4th Ed. this is in reference to Inserting Data into the Database, the code from page 139-141 …This is what I receive after adding a joke to the db…

Warning: Cannot modify header information - headers already sent by (output started at C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\addjoke\index.php:1) in C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\addjoke\index.php on line 60

I just downloaded the code form this site so I know there’s no typo’s etc., the jokes I try to add ARE being added to the database, just this redirect ?? Any help would be greatly appreciated !

Dennis

Hi beachjester, welcome to the forums,

I only have the 4 free sample chapters for the second edition.

The closest thing I see in the errata http://www.sitepoint.com/books/phpmysql4/errata.php is

p.138 2nd paragraph

The first sentence should read “… by letting you insert special headers into the response sent to the browser.”

If that’s any help.

“headers already sent” errors result anytime a file outputs anything, even whitespace, before a header()

Can you post the pertinent section of code from the index.php file?

Hi Mittineague and thank you so much for that welcome, and your help!

Below is the part of the code I believe is causing the problem ?

if (isset($_POST[‘joketext’]))
{
$joketext = mysqli_real_escape_string($link, $_POST[‘joketext’]);
$sql = ‘INSERT INTO joke SET
joketext="’ . $joketext . ‘",
jokedate=CURDATE()’;
if (!mysqli_query($link, $sql))
{
$error = 'Error adding submitted joke: ’ . mysqli_error($link);
include ‘error.html.php’;
exit();
}

header('Location: .');
exit();

}

$result = mysqli_query($link, ‘SELECT joketext FROM joke’);
if (!$result)
{
$error = 'Error fetching jokes: ’ . mysqli_error($link);
include ‘error.html.php’;
exit();
}

while ($row = mysqli_fetch_array($result))
{
$jokes = $row[‘joketext’];
}

That shows the header()

if (isset($_POST['joketext']))
{
$joketext = mysqli_real_escape_string($link, $_POST['joketext']);
$sql = 'INSERT INTO joke SET
joketext="' . $joketext . '",
jokedate=CURDATE()';
if (!mysqli_query($link, $sql))
{
$error = 'Error adding submitted joke: ' . mysqli_error($link);
include 'error.html.php';
exit();
}

header('Location: .');
exit();
}

So the problem is somewhere before this section of code.

If the code is not “going in and out of PHP” i.e. it has “<?php” and “?>” in it, then you may have a whitespace character before the file’s starting <?php tag, which should be the very first thing in the file’s code.

Or maybe there’s an echo() line outputting something?

Please post the lines of code that come before the code you already posted.

Mittineague, please check the code below, that is complete…thanks, D.

<?php
if (get_magic_quotes_gpc())
{
function stripslashes_deep($value)
{
$value = is_array($value) ?
array_map(‘stripslashes_deep’, $value) :
stripslashes($value);

	return $value;
}

$_POST = array_map('stripslashes_deep', $_POST);
$_GET = array_map('stripslashes_deep', $_GET);
$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
$_REQUEST = array_map('stripslashes_deep', $_REQUEST);

}

if (isset($_GET[‘addjoke’]))
{
include ‘form.html.php’;
exit();
}

$link = mysqli_connect(‘localhost’, ‘root’, ‘password’);
if (!$link)
{
$error = ‘Unable to connect to the database server.’;
include ‘error.html.php’;
exit();
}

if (!mysqli_set_charset($link, ‘utf8’))
{
$output = ‘Unable to set database connection encoding.’;
include ‘output.html.php’;
exit();
}

if (!mysqli_select_db($link, ‘edb1’))
{
$error = ‘Unable to locate the joke database.’;
include ‘error.html.php’;
exit();
}

if (isset($_POST[‘joketext’]))
{
$joketext = mysqli_real_escape_string($link, $_POST[‘joketext’]);
$sql = ‘INSERT INTO joke SET
joketext="’ . $joketext . ‘",
jokedate=CURDATE()’;
if (!mysqli_query($link, $sql))
{
$error = 'Error adding submitted joke: ’ . mysqli_error($link);
include ‘error.html.php’;
exit();
}

header('Location: .');
exit();

}

$result = mysqli_query($link, ‘SELECT joketext FROM joke’);
if (!$result)
{
$error = 'Error fetching jokes: ’ . mysqli_error($link);
include ‘error.html.php’;
exit();
}

while ($row = mysqli_fetch_array($result))
{
$jokes = $row[‘joketext’];
}

include ‘jokes.html.php’;
?>

Except for one error include-ing output.html.php instead of error.html.php which might be correct, but just seems curious, the code looks fine to me.

The error message
output started at C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\addjoke\index.php:1

Suggests to me that the “<” of the beginning “<?php” is not the very first character of the file. Perhaps it’s a BOM (Byte Order Mark - “signature”) that got added when you saved the file?

Depending on what text editor you use, a BOM may not be visible or may show as “funny looking characters”. Maybe try saving it again making sure you don’t use the signature, or try the file directly from the archive.

I’m just using notepad for this. Open program as administrator, saving with utf-8 encoding…but up to this point I have entered all the code by hand, to learn, and have had zero problems until this section (starting page 132)… so I downloaded the archive file to be sure I didn’t have a typo, etc. That’s when this header error started.

Is there a way I can confirm this BOM is not apart of this file ?

Any further ideas I’d love to hear…Even remote possibilities…? it has to be something…THANKS again Mitt

If the file is online somewhere you can find out if it has the BOM here http://people.w3.org/rishida/utils/bomtester/

My guess is Notepad is automatically adding the BOM when you save it as UTF-8 without showing you a “use signature” option. Try saving it as a “plain text” file. Maybe index.txt and then rename it to index.php

You are a bright one …

Problem solved. It was notepad! I extracted the downloaded file into Dreamweaver, saved it, then ‘dragged’ the file directly into the ‘addjoke’ folder and Voila!

… Thanks so much for your time Mittineague.

I also wanted to mention I downloaded Notepad++ and it is a new world with that editor. Presents the option to save with/without BOM. That is outstanding.

Odd thing is, AFAIK there is no use for a BOM with UTF-8. It’s critically important for UTF-16 and UTF-32, but only seems to cause problems with UTF-8

Hi all,

I’ve been scratching my head and searching the web for answers to this problem for a couple of days now and would really appreciate any available help in solving it.

My problem is identical to beachjester’s, but changing my editor and the encoding did not fix it for me.

I am receiving the message:

Warning: Cannot modify header information - headers already sent by (output started at C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\connect\index.php:8) in C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\connect\index.php on line 59

Here is the full code of my controller file:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=“http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv=“Content-Type” content=“text/html; charset=utf-8” />
<title>ijdb Controller</title>
</head>
<body>
<?php
if (get_magic_quotes_gpc())
{
function stripslashes_deep($value)
{
$value = is_array($value) ?
array_map(‘stripslashes_deep’, $value) :
stripslashes($value);
return $value;
}
$_POST = array_map(‘stripslashes_deep’, $_POST);
$_GET = array_map(‘stripslashes_deep’, $_GET);
$_COOKIE = array_map(‘stripslashes_deep’, $_COOKIE);
$_REQUEST = array_map(‘stripslashes_deep’, $_REQUEST);
}
if (isset($_GET[‘addjoke’]))
{
include ‘addJokeForm.html.php’;
exit();
}
$link = mysqli_connect(‘localhost’, ‘root’, ‘password’);
if (!$link)
{
$error = ‘Unable to connect to the database server.’;
include ‘error.html.php’;
exit();
}
if (!mysqli_set_charset($link, ‘utf8’))
{
$error = ‘Unable to set database connection encoding.’;
include ‘error.html.php’;
exit();
}
if (!mysqli_select_db($link, ‘ijdb’))
{
$error = ‘Unable to locate the joke database.’;
include ‘error.html.php’;
exit();
}
if (isset($_POST[‘joketext’]))
{
$joketext = mysqli_real_escape_string($link, $_POST[‘joketext’]);
$sql = ‘INSERT INTO joke SET
joketext="’ . $joketext . ‘",
jokedate=CURDATE()’;
if (!mysqli_query($link, $sql))
{
$error = 'Error adding submitted joke: ’ . mysqli_error($link);
include ‘error.html.php’;
exit();
}
header(‘Location: .’);
exit();
}
$result = mysqli_query($link, ‘SELECT joketext FROM joke’);
if (!$result)
{
$error = 'Error fetching jokes: ’ . mysqli_error($link);
include ‘error.html.php’;
exit();
}
while ($row = mysqli_fetch_array($result))
{
$jokes = $row[‘joketext’];
}
include ‘jokes.html.php’;
?>
</body>
</html>

Diagnosis so far:

Have searched high and low through this file, along with all of the associated include files for whitespace, and have stripped out anything that looks even remotely like whitespace.

Have edited the scripting files with Dreamweaver, TextEdit and Notepad++, changing the encoding type from ANSI to UTF8 without BOM, with no change.

Have tested the index.php file for a BOM signature using the w3.org tester. No BOM found.

The code referenced by the “…\connect\index.php:8” part of the error message is where my php starts, i.e. “<?php” is located on line 8.

The code referenced by the “…\connect\index.php on line 59” part of the error message is where the header function is called, i.e. “header(‘Location: .’);” is found on line 59.

Can anyone think of anything else I can try?

Many thanks.

It is not only a BOM that causes a “headers already sent” error, but any output at all before the header() call. It’s just that because a BOM is “invisible”, it causes a lot of problems unless you know about it and look for it.

Is the code you posted the entire connect/index.php file? If so the HTML before the PHP causes the file to output html/text headers. If it isn’t, what are the first 10 lines or so of the index.php file?

Thanks for the prompt reply Mittineague.

You asked: Is the code you posted the entire connect/index.php file?

Yes it is. In fact it is virtually verbatim the code Kevin Yank uses in the tutorial from chapter 4 in his Build Your Own Database Driven Website textbook.

If so the HTML before the PHP causes the file to output html/text headers

Can you please point out which HTML code is causing the file to output html/text headers, and why does this not happen all the time, such as when Kevin uses this code?

Many thanks for your help, it is greatly appreciated.

Check your includes for a carriage return after the closing php tag.

John

I’ve checked to ensure that all bogus whitespace and carriage returns have been deleted from all of my includes, thanks John.

In fact the only include that is being called regularly is the: include ‘addJokeForm.html.php’;
and this contains only HTML code, no PHP code.

However, I do believe that this include is somehow causing the problem, as when I comment it out of the index.php file the header problem no longer appears. I just can’t see how this include is causing the problem. I’ve cut and pasted the file below. Hopefully someone may be able to shed a little light on what’s going on. My head’s starting to hurt :injured: from all the banging against the wall it’s getting.

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=“http://www.w3.org/1999/xhtml”>
<head>
<title>Add Joke</title>
<meta http-equiv=“content-type” content=“text/html; charset=utf-8”/>

<style type=“text/css”>
textarea {
display: block;
width: 100%;
}
</style>
</head>
<body>
<form action=“?” method=“post”>
<div>
<label for=“joketext”>Type your joke here</label>
<textarea id=“joketext” name=“joketext” rows=“3” cols=“40”></textarea>
</div>
<div>
<input type=“submit” value=“Add”/>
</div>
</form>
</body>
</html>

Whatever it is, you can bet there’s some output coming from somewhere. The starting point is the error message:
connect/index.php 8
If that line itself (or one before it) doesn’t cause output i.e. an include, then the file that’s included is. If that file is the addJokeForm.html.php file, then scrutinize that. Maybe the empty line between meta and style?

That’s what I suspect as well Mittineague. It has to be something in the addJokeForm.html.php. I just can’t see what. I have removed the space between the meta and style, no change.

Incidently connect/index.php 8 is the positioning of the opening php tag i.e. <?php . Would this also point to the include statement as being the cause of the problem?

To avoid spending another two days on this problem I can sidestep the issue by replacing the header(‘Location: .’); command with the $_SERVER[‘PHP_SELF’]; command. This allows the rest of the index.php code to execute.

However, this prompts another question; what is the purpose of the exit(); command following the header(‘Location: .’); command?

If it executes the list of jokes do not get selected from the database and therefore cannot be displayed. If it is commented out, all jokes (including the new added joke) are displayed without any problems.

:confused:

Many thanks.
Grant

The “exit” (same as “die”) tells the PHP parser to stop executing the file at that point. It can be very important especially when you don’t want subsequent code to run.

Maybe if you downloaded the files from the book’s code archive and tried those. If they work OK then you can compare them with yours and hopefully see the difference.

If you copied and pasted the three files in the /includes directory you got an extra carriage return as I did. Open each file up and try and click after the closing php tag then press the down arrow key or right arrow key. If your curser moves down a line press the backspace key then the delete key. Make sure you can not place the curser past the closing php tag shown by position A. The index is opening one of the files from the /includes directory (I’m at work and forget which one).

?>A
B

If your curser can go to point B you have a carriage return after the closing tag.

It took me a day or two to figure it out! Once I got past that all was smooth and I actually have a new php mysql web site started based on the pattern in the book. So hang in there.

I’ll log in again this evening to check your progress.

John