0

Possible Duplicate:
Headers already sent by PHP

I fixed this problem, but since I don't understand what caused it, I can't be sure it's really fixed.

My PHP site displays the latest activity on the home page, before you log in. I recently modified the logic to include more types of activity. It looked like it worked, but I got the following error upon logging in:

Warning: Cannot modify header information - headers already sent by
(output started at header.php:75)
in index.php on line 26

I think this error message is misleading, because the way I fixed it was by changing "LIMIT 10" to "LIMIT 9" in the MySQL query that gets the activity to be displayed on the home page.

    public function getLatestActivity()
{
    $sql = "SELECT 'Debate' AS Type, d.Debate_ID AS ID, CONCAT('debate.php?debate_id=', d.Debate_ID) AS URL, d.Title, d.Add_Date
        FROM debates d

        UNION SELECT 'Discussion' AS Type, d.Discussion_ID AS ID, CONCAT('discussion.php?discussion_id=', d.Discussion_ID) AS URL, d.Title, d.Add_Date
        FROM discussions d

        UNION SELECT 'Petition' AS Type, p.Petition_ID AS ID, CONCAT('petition.php?petition_id=', p.Petition_ID) AS URL, p.Petition_Title AS Title, p.Add_Date
        FROM petitions p

        ORDER BY Add_Date DESC
        LIMIT 9";

    try
    {
        $stmt = $this->_db->prepare($sql);
        $stmt->execute();
        $activity = array();
        while ($row = $stmt->fetch())
        {
            $activity[] = '<span style="font-size: x-large"><strong>Latest activity</strong></span><br /><span style="font-size: large">' . $row['Type'] . ': <span style="color: #900"><a href="' . $row['URL'] . '" style="color: #900">' . $row['Title'] . '</a></span></span>';
        }
        $stmt->closeCursor();

        return $activity;
    }
    catch(PDOException $e)
    {
        return FALSE;
    }
}

And here's what I'm doing with the data returned by that function. It loops through the array and shows a new item every 4 seconds.

    <?php $latest_activity = $pdb->getLatestActivity(); ?>
<script type="text/javascript">
    var activity = <?php echo json_encode($latest_activity);  ?>;
    var index = -1;
    $(function()
    {
        getLatestActivity();
    });
    function getLatestActivity()
    {
        index = (index + 1) % activity.length;
        var div = document.getElementById('divLatestActivity');
        if (index < activity.length)
        {
            div.innerHTML = activity[index];
        }
        setTimeout("getLatestActivity()", 4000);
    }
</script>

Why did changing "LIMIT 10" to "LIMIT 9" fix the "cannot modify header information" problem?

Community
  • 1
  • 1
  • Changing it back to 10 does it still work? I think your file just never got saved correctly or uploaded correctly before. – kittycat Dec 30 '12 at 03:08
  • BTW, index.php line 26 is where the page reloads itself after verifying the login [header("Location: ./");]. header.php line 75 says "." – WhiteAlligator Dec 30 '12 at 03:10
  • I tried changing it back to 10 just now and it breaks. Changed it back to 9 and it works. – WhiteAlligator Dec 30 '12 at 03:13
  • 1
    See [Headers already sent](http://stackoverflow.com/questions/8028957/headers-already-sent-by-php) and why output buffering is just a workaround. Specifically the limited buffer size can lead to such odd cases. -- Use one of the mentioned redirection alternatives. – mario Dec 30 '12 at 03:13
  • @WhiteAlligator btw your column names should not be in quotes, they should be in backticks `\`` otherwise will be interpreted as strings not field names as far as I know. – kittycat Dec 30 '12 at 03:16
  • @cryptic, are you talking about where I have "SELECT 'Debate' AS Type?" That is indeed a string and not a field name. – WhiteAlligator Dec 30 '12 at 03:57
  • I suspect you're mistyping something when you set it to `limit 10`, and it's causing an error to be output. – Barmar Dec 30 '12 at 05:47

2 Answers2

0

In PHP, if you use the header() function (i.e. header("Location:login.php"); to redirect to the login.php page), you must do it before any other code that might output text to the browser.

//this will CAUSE a warning
echo "Login now";
session_start()
header("content-type:text/html");
header("cache-control:max-age=3600");

However...

//this will NOT CAUSES a warning
header("content-type:text/html");
header("cache-control:max-age=3600");
session_start();
echo "Login now";

So comb through your code that executes any session_start() or header() directives and make sure there are no echo ""; before them. If you have any MySQL warnings that are thrown out onto the page before your session_start() or header() that will also cause this warning.

chwagssd
  • 181
  • 6
  • I modified index.php to only include header.php if I'm not going to use the header() function. Now it works with "LIMIT 10." I don't see what was being output though - I can run the query in phpMyAdmin with no errors or warnings. The total size of the array strings is 2548 bytes - could the amount of data being returned cause a problem? – WhiteAlligator Dec 30 '12 at 03:54
0

You need to check if some output has been done in the form of echo, print or HTML. If this has been done, then header("LOCATION: login.php") will throw an error.

A way to over come this is using output buffering.

ob_start();

Prathik Rajendran M
  • 1,152
  • 8
  • 21
  • The code most presumably uses that already. – mario Dec 30 '12 at 03:15
  • I was not doing any output buffering deliberately, though I now see that my local php.ini file has "output_buffering = 4096", so maybe I have it enabled locally (where I did not get the error) but not on the server. – WhiteAlligator Dec 30 '12 at 04:11