如何修复PHP中的“Headers already sent”错误

时间:2011-11-06 17:41:23

标签: php header

运行我的脚本时,我收到了以下几个错误:

  

警告:无法修改标头信息 - 已经由 /some/file.php 上的输出/some/file.php:12 发送的标头< strong>第23行

错误消息中提到的行包含header()setcookie()次调用。

这可能是什么原因?以及如何解决它?

10 个答案:

答案 0 :(得分:190)

在发送HTTP标头(包含setcookieheader)之前发送任何时会触发此错误消息。在HTTP标头之前输出内容的常见原因是:

  • 意外的空格,通常在文件的开头或结尾,如下所示:

     <?php
    // Note the space before "<?php"
    ?>
    

为了避免这种情况,只需忽略结束?> - 无论如何都不需要。

  • Byte order marks在php文件的开头。用十六进制编辑器检查你的php文件,看看是否是这种情况。它们应该以字节3F 3C开头。您可以安全地从文件开头删除BOM EF BB BF
  • 显式输出,例如调用echoprintfreadfilepassthru<?之前的代码等。
  • 如果设置了display_errors php.ini属性,则由php输出警告。而不是崩溃程序员的错误,PHP默默地修复错误并发出警告。虽然您可以修改display_errorserror_reporting配置,但您应该解决问题 常见的原因是访问数组的未定义元素(例如$_POST['input']而不使用emptyisset来测试输入是否已设置),或使用未定义的常量而不是字符串文字(如$_POST[input]中所示,请注意缺少的引号)。

启用output buffering会使问题消失;调用ob_start后的所有输出都缓冲在内存中,直到释放缓冲区,例如与ob_end_flush

但是,虽然输出缓冲避免了这些问题,但您应该确定应用程序在HTTP标头之前输出HTTP主体的原因。这就像接听电话并讨论你的日期和天气,然后告诉来电者他的电话号码错误。

答案 1 :(得分:110)

我之前多次遇到过这个错误。我确信所有的PHP程序员至少都会遇到这个错误。 要解决此错误,您可以根据问题级别解决使用解决方案:

可能的解决方案1:

您可能在或之前(在文件末尾?&gt;之后)之前留下空格

THERE SHOULD BE NO BLANK SPACES HERE
<?php  

   echo "your code here";

?>
DO CHECK FOR BLANK SPACES HERE AS WELL; THIS LINE (blank line) SHOULD NOT EXIST.

大部分时间这都可以解决您的问题。请检查与您require文件相关联的所有文件。

注意: 有时像gedit(默认的linux编辑器)这样的EDITOR(IDE)会在保存文件中添加一个空行。这不应该发生。如果你使用的是linux。您可以使用VI编辑器删除空格/行后?&gt;在页面的末尾。

如果不是这种情况,那么您可以使用ob_start进行输出缓冲,如下所示:

可能的解决方案2:

<?php
  ob_start();

  // code 

 ob_end_flush();
?> 

这将打开输出缓冲,并在页面缓冲后创建标题。

答案 2 :(得分:80)

而不是下面的行

//header("Location:".ADMIN_URL."/index.php");

echo("<script>location.href = '".ADMIN_URL."/index.php?msg=$msg';</script>");

?><script><?php echo("location.href = '".ADMIN_URL."/index.php?msg=$msg';");?></script><?php

这肯定会解决你的问题。 我遇到了同样的问题,但我通过以上述方式编写标题位置来解决。

答案 3 :(得分:39)

你做

printf ("Hi %s,</br />", $name);

在设置cookie之前,这是不允许的。您不能在标题之前发送任何输出,甚至不能发送空行。

答案 4 :(得分:32)

这是因为这一行:

printf ("Hi %s,</br />", $name);

在发送标题之前,您不应该 打印/回显

答案 5 :(得分:28)

常见问题:

(复制自:source

====================

1) echo.. 之前不应有任何输出(即 header(.......); 或HTML代码)命令。

2)<?php之前和?>标记之后删除任何空白(或换行)。

3) GOLDEN RULE! - 检查该php文件(以及include其他文件)是否 UTF8没有BOM < / strong>编码(而不仅仅是 UTF-8 )。这在许多情况下都是问题(因为 UTF8 编码文件在php文件的开头有一些特殊字符,你的文本编辑器没有显示)!!!!!!!!!!!

4) header(...);之后您必须使用exit;

5)始终使用301或302引用:

header("location: http://example.com",  true,  301 );  exit;

6) 启用错误报告,然后查找错误。您的错误可能是由无效的功能引起的。当您打开错误报告时,您应该始终首先修复最顶层的错误。例如,它可能是&#34;警告:date_default_timezone_get():依靠系统的时区设置是不安全的。&#34; - 然后再下来你可能会看到#34;标题没有被发送&#34;错误。修复最顶层(第一个)错误后,重新加载页面。如果您仍有错误,请再次修复最错误的错误。

7)如果以上都没有帮助,使用JAVSCRIPT重定向(但是,非强烈推荐的方法),可能是自定义案例中的最后一次机会......:

echo "<script type='text/javascript'>window.top.location='http://website.com/';</script>"; exit;

答案 6 :(得分:26)

一个简单的提示:脚本中的一个简单空格(或不可见的特殊字符),就在第一个<?php标记之前,可能会导致这种情况发生! 特别是当你在一个团队中工作,有人正在使用“弱”IDE或者在文件中乱用奇怪的文本编辑器时。

我见过这些东西;)

答案 7 :(得分:21)

另一个不好的做法可以调用这个尚未说明的问题。

请参阅以下代码段:

<?php
include('a_important_file.php'); //really really really bad practise
header("Location:A location");
?>

一切都好,对吧?

如果“a_important_file.php”是这样的话:

<?php
//some php code 
//another line of php code
//no line above is generating any output
?>

 ----------This is the end of the an_important_file-------------------

这不行吗?为什么?因为已经生成了新行。

现在,虽然这不是一个常见的情况,如果您使用的MVC框架在将内容切换到控制器之前加载了大量文件,那该怎么办?这不是一种罕见的情况。为此做好准备。

来自PSR-2 2.2 :


  • 所有PHP文件必须使用Unix LF (linefeed) line ending
  • 所有PHP文件必须以single blank line结尾。
  • 结束?&gt;标签必须是包含omitted
  • 的文件中的only php

相信我,按照这些标准可以为你节省大量的时间:)

答案 8 :(得分:15)

有时当开发进程有WIN工作站和LINUX系统(托管)时,在代码中你没有看到相关行之前的任何输出,它可能是文件的格式化和缺少 Unix LF(换行)  行结束。

我们通常为了快速修复此问题而重命名文件,并在LINUX系统上创建一个新文件而不是重命名文件,然后将内容复制到该文件中。很多时候,这解决了这个问题,因为在WIN中创建的一些文件一旦移动到托管就会导致此问题。

此修复程序是我们通过FTP管理的网站的一个简单修复,有时可以节省我们的新团队成员。

答案 9 :(得分:2)

通常在回显或打印后发送标题时会出现此错误。如果在特定页面上出现此错误,请确保在呼叫start_session()之前该页面没有回显任何内容。

不可预测的错误示例:

 <?php //a white-space before <?php also send for output and arise error
session_start();
session_regenerate_id();

//your page content

又一个例子:

<?php
includes 'functions.php';
?> <!-- This new line will also arise error -->
<?php
session_start();
session_regenerate_id();

//your page content

结论:在调用session_start()header()函数之前不要输出任何字符,甚至不是空白行或新行