Looking over your code, it looks like your logic is already structured such that output need not be sent to the client before a header() call. As such, another possibility is that you have one or more blank lines at the top of your script, and these lines are being interpreted as output.
Incidentally, you can simply your code with the use of elseif:
<?php
session_start();
if (isset($_POST['logout'])) {
session_destroy();
echo "You have succesfully logged out! Click <a href='login.php'>here</a> to proceed!";
} elseif (isset($_SESSION['logged'])) {
header("Location: index.php");
?>
<form method='POST' action='login.php'>
<input type='submit' value='logout' name='logout'>
</form>
<?php
} elseif (isset($_POST['submit'])) {
$sql = $db->sql_query("SELECT w_account, pwd FROM director WHERE w_account = '"
. $_POST['username'] . "' && pwd='" . md5($_POST['password']) . "' ");
$count = mysql_num_rows($sql);
if ($count == 1) {
$_SESSION['logged'] = true;
$_SESSION['w_account'] = $_POST['w_account'];
$_SESSION['pwd'] = $_POST['pwd'];
header("Location: index.php");
} else { //if the username and password don't exist
echo "<font color='red'>Incorrect login! Please try again</font>";
if (isset($HTTP_REFERER)) {
echo "<a href='$HTTP_REFERER'>[Back]</a>";
} else {
echo "<a href='javascript:history.back()'>[Back]</a>";
}
}
} else { //if the user didn't press on the submit(login) button yet, show the form
?>
<form method='POST' action='login.php'>
<input type='text' name='username'><b>w_account:</b><br>
<input type='password' name='password'><b>password:</b><br>
<input type='submit' value='login' name='submit'>
</form>
<?php
}
?>
Once again, I note that the location header should be to an absolute URL, and that it should have an exit or die after it. As such, printing a form after sending a location header is useless work, yet this is what happens if $_SESSION['logged'] is set.
I expect that the script it still in development, but please note that you are not handling incoming variables properly. For example, it is possible to craft an SQL injection via $_POST['username'].
I also note that taking a cryptographic hash of the password is only useful to protect your users' passwords (which may be reused on other websites) in the event that your database is compromised. Consequently, a simple MD5 hash would be susceptible to an offline attack using rainbow tables. You should have a user specific salt to make this more difficult, and use at least SHA1 instead of MD5 (more time-expensive hash algorithms may be available via [man]hash/man ). Repeated hashing may also help.