Headers already sent error

Good evening everyone. I know this question has been asked many many times, but I’m completely stuck. I just can’t figure out what is wrong with my code. It worked perfectly fine for 3 years (yes!) and now I get this error when I try to log in:

Warning:  Cannot modify header information - headers already sent by (output started at /var/www/vhosts/witjassies.co.za/httpdocs/licenseholderslogin.php:5) in /var/www/vhosts/witjassies.co.za/httpdocs/licenseholderslogin.php on line 68

I am a TOTAL beginner when it comes to PHP (only know the very basics), so I really do need help as this is a client’s website.

Can someone please tell me what is wrong with this code:

<?php
    session_start();
    ?>
    
    <?php 
    // Script Error Reporting
    error_reporting(E_ALL);
    ini_set('display_errors', '1');
    ?>
    
    <!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>Die Witjassies &#38; Little Lab Coats | License Holders Login</title>
      <meta http-equiv="Content-type" content="text/html; charset=us-ascii" /> 
      <meta http-equiv="Content-Language" content="en-us" />
      <meta http-equiv="imagetoolbar" content="no" />
      <meta name="MSSmartTagsPreventParsing" content="true" />
      <meta name="description" content="" />
      <meta name="keywords" content="" />
      <meta name="author" content="Susan Venter" />
      <link rel="stylesheet" href="css/style.css" type="text/css" />
    </head>
    
    <body>
    
    <div id="page-container">
    
        <div id="header">
        <?php
        include "scripts/header.php";
        ?>
        </div>
        
        <div id="spacer">
        </div>
        
        <div id="left-panel">
        
        <div class="box1">
        <?php
        include "scripts/menu.php";
        ?>
        </div>
        
        <div class="box2">
        <?php
        include "scripts/contact.php";
        ?>
        </div>
        
        </div>
        
        <div id="right-panel">
        
        <div class="box3">
        <center>
        <?php
        mysql_connect('...')
        or die ("Could not connect to mysql because ".mysql_error());
        mysql_select_db('...')
        or die ("Could not select database because ".mysql_error());
        if(mysql_num_rows(mysql_query("SELECT * FROM users WHERE username='".$_POST["username"]."' and password='".$_POST["password"]."'"))==1){
        session_register("username");
        $_SESSION['username']=$_POST["username"];
        header("location:index.php");
        }
        else {
           echo 'The username and password you entered are incorrect.';
        }
        ?>
        <br />
        <a href="licenseholders.php">Please try again.</a>
        </center>
        </div>
        
        <div class="box3">
        <div class="text3">License Holders / Lisensiehouers</div><br />
        <br />
        <div class="text3">...</div>
        <a href="mailto:...">...</a><br />
        ...<br />
        <br />
        <div class="text3">...</div>
        <a href="mailto...">...</a><br />
        ...<br />
        <br />
        <div class="text3">...</div>
        <br />
        <div class="text3">...</div>
        <br />
        <br />
        </div>
        
        </div>
            
        <div id="footer">
        <?php
        include "scripts/footer.php";
        ?>
        </div>
        
    </div>
    </body>
    </html>

I’d be forever grateful if someone could point me in the right direction!

Kind regards,
Susan

I can’t see how it worked without error before, though I am learning PHP myself. You output a load of stuff to the browser, and then (around line 68, as per the error message) you then attempt to send a header to redirect to index.php. Because you’ve already sent stuff to the browser, you get the error message. There are ways to buffer the output, but you don’t seem to be using them, or I can’t see them at least. If your PHP code that connects to the database will run anyway, is there any point outputting all that HTML at the top if you then intend it to redirect to another page? Surely it would be better to only output that if the login fails?

What changed from when it was working, to when you started getting the error message? Change of hosting environment, for example?

Also you need to look at how you access the database - the old-style mysql library calls that you have in there are being deprecated and you should look at mysqli or PDO. PDO and prepared statements would help protect you from injection attacks that your code above may be open to.

Yes, all the DB query and resulting messages should be done above <!DOCTYPE ...

If there is a message e.g. echo 'The username and password you entered are incorrect.';
Set this to a variable to echo within the page.
If using header("Location: ... do this above output and be sure to follow that line with exit;

The spaces in there are enough to trigger a headers already sent error as those spaces are sent as content and content comes after the headers.

Thank you all for your replies - it is much appreciated. I have now managed to fix it by adding ob_start(); to the top of the page. My knowledge of PHP is honestly not the best - something I plan on changing very soon.

Kind regards,
Susan

Presumably then you will fix it to get rid of the ob_start()

PHP is much cleaner if you write the headers first and then write the content. There are very few situations (relatively) where you don’t know what headers to write before starting to process the content.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.