【问题标题】:Why can't I use session_start() in my php script? It says headers are already sent为什么我不能在我的 php 脚本中使用 session_start()?它说标头已经发送
【发布时间】:2010-10-17 06:34:30
【问题描述】:

这是我页面的前几行:

<!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;}
?>

我收到以下错误:

无法发送会话 cookie - 第 2 行 /usr/www/users/simpleof/index.php 中的标头(输出开始于 /usr/www/users/simpleof/index.php:2)

根据我在其他论坛上阅读的内容,这应该没问题,因为 session_start() 位于 php 代码的第一块中,但我仍然收到此错误。

【问题讨论】:

  • 会话必须在发送任何输出之前启动,因为它使用在 HTTP 请求标头中指定的 cookie,这显然是在请求正文之前发送的。
  • dblogin.php 中一定有一些东西正在写入客户端。一旦开始写入客户端,您就不能再发送标头(并且启动会话会发送一个标头,告诉客户端创建 php 会话 id cookie)。您可以通过设置输出缓冲来绕过它。

标签: php session cookies header


【解决方案1】:

HTTP 协议的工作原理如下:

您使用浏览器发送此类标头:

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

第一台服务器向您发送标头:

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

然后服务器向你发送实际的页面数据

<!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..

所以您看到您不能先发送 HTML 数据 (DOCTYPE),然后再发送标头数据,因为标头已被处理。您可以使用 PHP 的 Output Control,但更推荐使用 MVC 设计,在该设计中缓冲用户最后看到的所有数据。

【讨论】:

    【解决方案2】:

    您要么误读,要么其他论坛有误。仅仅因为session_start() 在 PHP 代码的第一个“块”中并不意味着它会起作用。

    session_start() 需要在发送标头之前运行。

    您的解决方案是:

    session_start();移到&lt;!DOCTYPE html上方...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-13
      • 1970-01-01
      • 2015-05-29
      • 1970-01-01
      • 2011-01-22
      • 1970-01-01
      相关资源
      最近更新 更多