Logging out puts a new record in the database

Ok, here’s the problem.

On my index page I got a login form för the admin page. It works just fine.

On the admin page I can add articles to the mysql database. Works fine.

I can also delete and edit articles without problem. The problem occurs when I log out from the admin page. Tog log out I simply use this:

if (isset($_POST['logout']))
{
session_destroy();
}

The logout sends me back to the index page, which is what I want. But if I log in again, a new emtpy record has been added to the database. It looks like it is the log out that adds it. It looks like it is connected to a reload of the page. How do I prevent the browser from reloading the page before quiting?

instead of echoing the data, store the information in a variable… then output it in the appropriate div later on.

It could look something like this:


<?php
session_start();
// check for login, redirect and exit if not logged in

$error = false;
if(isset($_POST['insert']))
{
   // sanitize data
   // build query
   if(mysql_query($query))
   {
      // here you could store a message in session for display after redirect.
      header('location: admin.php');
      exit();
   }
   else
   {
      $error = "some error occured...";
   }
}

if(isset($_POST['update']))
{
   // pretty much the same thing as previous if statement...
}

// notice no output above this line...
?>
<html>
....
<body>
   <div>
<?php
if($error)
{
   echo $error;
}
?>
   </div>
</body>
</html>

Thanks zalucius, I will try that after the weekend! Many thanks!

Hmmm… But, let’s say I have a form which makes it possible for me to add/edit the database. In order do give the admin page a nice design aI put the php code in different divs and use css to position these divs.
How can I accomplish that if it is forbidden to echo something before using header? If I understand you, all headers must go before the html code and if that is true it is virtually impossible to design the page.

Be sure that no file or script can echo anything before you use header().
Plus, see, if there are any spaces or other white space characters before you begin your code.

Each php script’s very first letters should probably be: “<?php”. Not even the HTMLs.

Avoid what you have at admin.php on line 165 - some echo or any kind of output might have been there, like print, print_r. Don’t write such, before header() calls.

An included file like error.html.php too should not give out any outputs before header().

Got some more information. here’s the error message:

Warning: Cannot modify header information - headers already sent by (output started at C:\\Program Files (x86)\\Apache Software Foundation\\Apache2.2\\htdocs\\authors.html.php:17) in C:\\Program Files (x86)\\Apache Software Foundation\\Apache2.2\\htdocs\\admin.php on line 165

Here is authors.html.php:

<?php include 'helpers.inc.php';?>
<?php foreach ($authors as $author): ?>

<form action="" method="post">
<div>
<?php echo "<table>";?>
<?php echo "<tr>";?>
<?php echo "<td id='td1'>";?>
<?php htmlout($author['namn']); ?>

<input type="hidden" name="id" value="<?php
echo $author['id']; ?>" />
<?php echo "</td>";?>
<?php echo "<td id='td2'>";?>
<input type="submit" name="action" value="Edit" />
<input type="submit" name="action" value="Delete" />
<?php echo "</td>";?>
<?php echo "</tr>";?>
<?php echo "</table>";?>
</div>
</form>

<?php endforeach; ?>

Here is the troubling line in admin.php:

header('Location: update.php');

Just as I thought “It works!”, a new problem surfaced - the classic(?) “Warning: Cannot modify header information - headers already sent”.

Here is the Edit form (changes the content of the database):

if (isset($_POST[uppdatera]))
{
	include 'connect.php';
$rubrik = mysqli_real_escape_string($link, $_POST['rubrik']);
$brodtext = mysqli_real_escape_string($link, $_POST['brodtext']);
$id = mysqli_real_escape_string($link, $_POST['id']);
$sql = "UPDATE artiklar SET
artikel='$brodtext',
namn='$rubrik'
WHERE id='$id'";
if (!mysqli_query($link, $sql))
{
$error = 'Error updating submitted joke.';
include 'error.html.php';
exit();
}
header('Location: update.php');
exit();
}

On the update.php there is a message “The update was successful”.

When I click the update button the headers already sent error message appears.

This is the entire admin.php:

<div id="header">
  	if(isset($_SESSION['mypassword']))
	{
	echo "<p id='welcome'>Welcome " . $_SESSION['myusername'] . ", you are logged in! </p>";
	echo "<h1> Webbadministration</h1>"; 
	}
	else
	{
	header("location:index.php");
	session_destroy();
	}
</div>


<div id="container">
<div id="lagg_till">
<h3> Add content</h3>

  <form action="" id="form1" method="post">
    <div>
      <label for="namn">Artikelrubrik:</label><br />
      <input name="namn" type="text" id="namn"  style="width:400px;" /><br /><br />
      <label for="artikel">Artikeltext:</label><br />
      <textarea id="artikel" name="artikel" rows="20" cols="60"></textarea><br /><br />
            <label for="datum">Datum:</label><br /><br />
<input name="datum" type="text" id="datum" /><br />
    </div>
    <div><input type="submit" value="Add"/></div>
 
  </form>

</div>
<a href="http://localhost/" id="home">Home</a>
<?php

//---------------INSERT INTO DATABASE---------------------------
include 'connect.php';


if (isset($_POST['namn']))
{
$namn = mysqli_real_escape_string($link, $_POST['namn']);
$artikel = mysqli_real_escape_string($link, $_POST['artikel']);
$datum = mysqli_real_escape_string($link, $_POST['datum']);
$sql = 'INSERT INTO artiklar SET
namn="' . '<h3>' . $namn . '</h3>' . '",
datum="' . $datum . '",
artikel="' . '<p>' . $artikel . '</p>' . '"';

if (!mysqli_query($link, $sql))
{
$error = 'Error adding submitted joke: ' . mysqli_error($link);
include 'error.html.php';

}
header('Location: add.php');
exit();
}
?>





<div id="edit">

<h3>Artikellista</h3>
<?php
include 'connect.php';

//---Show Content--------------


$result = mysqli_query($link, 'SELECT id, namn FROM artiklar ORDER BY datum DESC');
if (!$result)
{
$error = 'Error fetching artikelrubrik from database!';
include 'error.html.php';
exit();
}
while ($row = mysqli_fetch_array($result))
{
$authors[] = array('id' => $row['id'], 'namn' => $row['namn']);
}
include 'authors.html.php';

//---- Delete Content---------------

if (isset($_POST['action']) and $_POST['action'] == 'Delete')
{

  $id = mysqli_real_escape_string($link, $_POST['id']);


  // Delete quotes belonging to author
  $sql = "DELETE FROM artiklar.artiklar WHERE artiklar.ID =  '$id'"; 
  
  if (!mysqli_query($link, $sql))
  {
    $error = 'Error deleting jokes for author.';
    include 'error.html.php';
    exit();
  }
header('Location: admin.php');
}


//---- Edit Content---------------

if (isset($_POST['action']) and $_POST['action'] == 'Edit')
{
include 'connect.php';
$id = mysqli_real_escape_string($link, $_POST['id']);
$sql = "SELECT id, namn, artikel FROM artiklar WHERE id='$id'";	
$result = mysqli_query($link, $sql);

while ($row = mysqli_fetch_array($result))
{

include 'testing.php';

}
}


//-------------EDIT---------------------------

if (isset($_POST['updatera']))
{
	include 'connect.php';
$rubrik = mysqli_real_escape_string($link, $_POST['rubrik']);
$brodtext = mysqli_real_escape_string($link, $_POST['brodtext']);
$id = mysqli_real_escape_string($link, $_POST['id']);
$sql = "UPDATE artiklar SET
artikel='$brodtext',
namn='$rubrik'
WHERE id='$id'";
if (!mysqli_query($link, $sql))
{
$error = 'Error updating submitted joke.';
include 'error.html.php';
exit();
}
header('Location: update.php');
exit();
}

</div>
<div id="footer">The PHP Webpage, 2003-<?php echo date('Y');?></div>
</div>
</body>
</html>

Ok, I tried your suggestion and it works. Instead of:

header('Location: admin.php');

I used this:

header('Location: update.php');

In the update.php, I did put a link back to admin.php so I can get there if I want to edit some more. One question though: this means that every time I edit a page I must leave the admin page for the update page in order to avoid the described problem with empty records.
Can you get the same result without the update page?

on the admin page, what do you check for, before inserting into the database?
something like this?

if(isset($_POST['submit'])){
 // ... inserting etc..
} 

can you post the code from your admin page?

This is the PHP code:

if (isset($_POST[edit]))
{
	include 'connect.php';
	
$rubrik = mysqli_real_escape_string($link, $_POST['rubrik']);
$brodtext = mysqli_real_escape_string($link, $_POST['brodtext']);
$id = mysqli_real_escape_string($link, $_POST['id']);
$sql = "UPDATE artiklar SET
artikel='$brodtext',
namn='$rubrik'
WHERE id='$id'";
if (!mysqli_query($link, $sql))
{
$error = 'Error updating submitted joke.';
include 'error.html.php';
}
header('Location: admin.php');
exit();
}

It is the header part that causes the problem? I redirect to the same page that holds the form.

Did you mean a new blank article is added?

Your logout script is okay. But you can add more, like:


$_SESSION = array();

if(isset($_COOKIE[session_name()]))
{
	setcookie(session_name(), '', time()-86400, '/');
}

session_destroy();

Here are few more suggestions:

Right after you add something into the database, redirect it to the add-successful page.
Don’t just show the add-successful message in the same page (which can be refreshed by the user to add a duplicate copy of the article).

Make sure that your script (index) adds articles only for successfully logged in users, and they have pressed the add button in the form.

Don’t put the INSERT SQL in your page that is loaded frequently (index). And just after inserting some data, redirect to other page. Use die(header(‘Location: add-successful.php’)); to prevent loading. Here, if the user loads the page, the add-successful page is loaded, which does not have any INSERT sqls within it.

Hope, this helps you conceptually.