4

Possible Duplicate:
“Warning: Headers already sent” in PHP

I have an error that displays on my PHP login form, when I upload it to my server. It was working perfectly on my localhost, but when I upload it to server it gives me this error:

Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at /home/shopping/public_html/biblioteka/index.php:10) in /home/shopping/public_html/biblioteka/index.php on line 45

Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at /home/shopping/public_html/biblioteka/index.php:10) in /home/shopping/public_html/biblioteka/index.php on line 45

Warning: Cannot modify header information - headers already sent by (output started at /home/shopping/public_html/biblioteka/index.php:10) in /home/shopping/public_html/biblioteka/index.php on line 49

And here is my PHP code:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <link rel="stylesheet" type="text/css" href="http://localhost/Shopping_biblioteka/css/style.css">
        <title>Title</title>
    </head>
    <body align="center">
        <div id="login">
        <?php
    
        if (isset($_POST['username']) && isset($_POST['password'])) {
            $username = $_POST['username'];
            $password = $_POST['password'];
            mysql_connect("localhost", "user", "pass") or die(mysql_error());
            mysql_select_db("db") or die(mysql_error());
        mysql_query("SET CHARACTER SET utf8");
        mysql_query("SET NAMES utf8");
            $result = mysql_query("SELECT password,id FROM x9qg6_users
            where username='" . $username . "'");
            if (!$result) {
                echo 'Could not run query: ' . mysql_error();
                exit;
            }
            $row = mysql_fetch_row($result);
            $test = explode(":", $row[0]);
            $user_id=$row[1];
            $userhash = md5($password . $test[1]);
            if ($test[0] === $userhash) {       
                session_start();
                $_SESSION['login_user'] = $user_id;
                $_SESSION['username'] = $username;
                $url = "biblioteka.php";
                header("Location: $url");
            }
        } else {
            echo 'Внесете ги вашите податоци во полињата!';
        }
        // Connects to your Database 
        ?> 
        <form action="" method="POST" accept-charset="UTF-8"> 
            Корисничко име:<br/>
            <input name="username" id="username" type="text"/><br/>
            Лозинка:<br/>
            <input type="password" id="password" name="password"/><br/>
            <input type="submit" value="Логирај се!"/>
        </form>

        </div>
    </body>
</html>
peterh
  • 11,875
  • 18
  • 85
  • 108
Chris
  • 67
  • 1
  • 3
  • 7

5 Answers5

6

Just add ob_start() after session_start()

<?php
session_start();
ob_start();
?>
<!DOCTYPE html>
<html>
    <head>
       ...
       ...
Pintu Francis
  • 486
  • 3
  • 11
  • 1
    This may fix the current problem, but it introduces a whole range of other problems in the OP's code. What if the query doesn't run? Your browser will be stuck with broken HTML (because of the `exit` call there). The OP's **design** is broken and fixing with a patch will create nasty things. This is how PHP gets its bad name. @Chris should read up on the HTTP protocol and design paradigms like MVC and the lot. – Bart Friederichs Dec 06 '12 at 11:16
  • i too had this problem, this solution works fine for me. – Tony Jose Dec 06 '12 at 11:16
4

Yes, your issue is that you are trying to send headers (by calling *session_start*) after you have already sent some output. This could be anything from HTML/whitespace/error-messages/etc.. that occurred before you called on *session_start*.

In the HTTP protocol those headers must come before the body of the request/response and since you've inadvertently started to send output you are already in the body and can't go back to the header.

One solution is to always make sure you call *session_start* before you do anything else. Another option is to use output buffering functions like ob_start() to buffer any output just in case.


Just in case you are wondering what's really happening that causes this here's a brief explanation of what session_start normally does... The normal behavior for a PHP session is to do 3 things when you call the function session_satrt()

  1. The session handler checks if the client has supplied a session id (normally by sending a cookie in the HTTP request header with the specified session.name). If one is found the session handler opens that session (by default that's a file -- if it doesn't exist it's created). If no session id is supplied by the client a random session id is generated and that session file is opened.
  2. The session handler than populates any data found in the session file into the $_SESSION supperglobal variable (i.e. the session is de-serialized).
  3. If in step 1 no Session ID was supplied (the session cookie) then the session handler sets a Set-Cookie header to be sent with the HTTP response.
Sherif
  • 11,786
  • 3
  • 32
  • 57
1

you must not output anything to the page before sent the header

or use output buffering

ob_start();
NullPoiиteя
  • 56,591
  • 22
  • 125
  • 143
1

Make sure you do not send anything (not even whitespace) before the session_start() or header() call:

<?php
     ...
     session_start();
     ...
     header();
     ...

?>
<!-- HTML code -->

More info can be found on the session_start documentation page.

session_start will send information in the HTTP headers (a piece of information sent to the browser, before any real content is sent). If you have already sent content to the browser, e.g. in your case quite some HTML code, the server cannot send that information in the headers: they are already gone. Read more on the HTTP protocol to understand the whole thing better.

Bart Friederichs
  • 33,050
  • 15
  • 95
  • 195
1

Move session_start(); to top of the file.

<?php
session_start();
?>
<!DOCTYPE html>
<html>
    <head>
       ...
       ...
Muthu Kumaran
  • 17,682
  • 5
  • 47
  • 70
  • moved session_start() on top and now gives me this error Warning: Cannot modify header information - headers already sent by (output started at /home/shopping/public_html/biblioteka/index.php:13) in /home/shopping/public_html/biblioteka/index.php on line 52 – Chris Dec 06 '12 at 10:59
  • @Chris: that's your `header()` call. Same problem. Read up on the HTTP protocol, it'll help understand what's going on. – Bart Friederichs Dec 06 '12 at 11:01
  • It's caused by `header("Location: $url");`. You can put `ob_start()` at the top of the file or move your php code at top of the HTML code. – Muthu Kumaran Dec 06 '12 at 11:04