Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I use session_start() in my php script? It says headers are already sent

Here are the first few lines of my page:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<?php include_once "dblogin.php";
session_start();
$loggedIn = 0;
if(isset($_SESSION["login"])) {$loggedIn = 1;}
?>

I'm getting the following error:

Cannot send session cookie - headers already sent by (output started at /usr/www/users/simpleof/index.php:2) in /usr/www/users/simpleof/index.php on line 2

From what I've read on other forums, this should be fine because the session_start() is in the first block of php code, but I'm still getting this error.

like image 634
cstack Avatar asked Dec 23 '22 12:12

cstack


2 Answers

Here's how HTTP protocol works:

You send this kind of header with your browser:

GET /questions/712326/why-cant-i-use-sessionstart-in-my-php-script-it-says-headers-are-already-sen HTTP/1.1
Host: stackoverflow.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fi; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fi-fi,fi;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://stackoverflow.com/questions/tagged/php
Cookie: *censored*
Cache-Control: max-age=0

First server sends you headers:

HTTP/1.x 200 OK
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Expires: Fri, 03 Apr 2009 02:14:49 GMT
Vary: Accept-Encoding
Server: Microsoft-IIS/7.0
Set-Cookie: *censored*
Date: Fri, 03 Apr 2009 02:14:49 GMT
Content-Length: 9346

Then server sends you the actual page data

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd" >
<html>
<head>    

    <title>Why can't I use session_start() in my php script? It says headers are already sent. - Stack Overflow</title>
    <link rel="stylesheet" href="/Content/all.min.css?v=2743">
   ..snip..

So you see you can't FIRST send HTML data (DOCTYPE) and then header data because header is already processed. You can go around with PHP's Output Control but more recommended is that you use MVC design where you buffer all data that user sees last.

like image 111
raspi Avatar answered Jan 14 '23 15:01

raspi


You either misread or the other forums are wrong. Just because session_start() is in the first "block" of PHP code doesn't mean it will work.

session_start() needs to be run before the headers are sent.

The solution in your case is:

Move session_start(); above <!DOCTYPE html...

like image 34
Travis Avatar answered Jan 14 '23 14:01

Travis