简明现代魔法 -> PHP服务器脚本 -> Header中Cannot modify header 错误的解決方法

Header中Cannot modify header 错误的解決方法

2010-03-29

今天在用 PHP 输出 XML 的时候,用到了 Header() 函数,同时也需要 echo 某个变量,它们产生了冲突。google了一下,找到几种解决方法,翻译整理一下:

If you got this message: "Warning: Cannot modify header information - headers already sent by ...."

如果在执行php程序时看到这条警告:"Warning: Cannot modify header information - headers alreadysent by ...."

Few notes based on the following user posts:

有以下几种解决方法:

  1. Blank lines (空白行):
  2. Make sure no blank line after <?php ... ?> of the calling php script.

    检查有<?php ... ?> 后面没有空白行,特别是include或者require的檔。不少问题是这些空白行导致的。

  3. Use exit statement (用exit来解决):
  4. Use exit after header statement seems to help some people

    在header后加上exit();

    header ("Location: xxx"); 
    exit();
    
  5. PHP has this annoying problem, if your HTML goes beforeany PHP code or any header modification before redirecting to certain page,it'll said "Warning: Cannot modify header information - headers alreadysent by ...." Basically anytime you output to browser, the header is setand cannot be modified. So two ways to get around the problem:
    • Use Javascript (用Javascript来解决):
    • <? echo "<script> self.location(\"file.php\");</script>";?>
      

      Since it's a script, it won't modify the header until execution of Javascript.

      可以用Javascript来代替header。但是上面的这段代码我没有执行成功... 另外需要注意,采用这种方法需要浏览器支持Javascript。

    • Use output buffering (用输出缓存来解决):
    • <?php ob_start(); ?>
      ... HTML codes ...
      <?php
      ... PHP codes ...
      header ("Location: ....");
      ob_end_flush();
      ?>
      

      This will save the output buffer on server and not output to browser yet, whichmeans you can modify the header all you want until the ob_end_flush()statement. This method is cleaner than the Javascript since Javascriptmethod assumes the browser has Javascript turn on. However, there are overheadto store output buffer on server before output, but with modern hardware Iwould imagine it won't be that big of deal. Javascript solution would bebetter if you know for sure your user has Javascript turn on on their browser.

      就像上面的代码那样,这种方法在生成页面的时候缓存,这样就允许在输出head之后再输出header了。我这里就是采用这种方法解决的header问题。

  6. set output_buffering = On in php.ini(开启php.ini中的output_buffering )
  7. set output_buffering = On will enable output buffering for all files. But thismethod may slow down your php output. The performance of this method depends onwhich Web server you're working with, and what kind of scripts you're using.

    这种方法和上一个方法理论上是一样的。但是这种方法开启了所有php程序的输出缓存,这样做可能影响php执行效率,这取决于服务器的性能和代码的复杂度。

一般来说在header函数前不能输出html内容,类似的还有setcookie() 和 session 函数,这些函数需要在输出流中增加消息头部信息。如果在header()执行之前有echo等语句,当后面遇到header()时,就会报出 “Warning: Cannot modify header information - headers already sent by ....”错误。就是说在这些函数的前面不能有任何文字、空行、回车等,而且最好在header()函数后加上exit()函数。例如下面的错误写法,在两个php代码段之间有一个空行:

<?php
  //some code here
?>
//这里应该是一个空行
<?php
    header("http/1.1 403 Forbidden");
    exit();
?>

原因是:PHP脚本开始执行 时,它可以同时发送http消息头部(标题)信息和主体信息. http消息头部(来自 header() 或SetCookie() 函数)并不会立即发送,相反,它被保存到一个列表中. 这样就可以允许你修改标题信息,包括缺省的标题(例如Content-Type 标题).但是,一旦脚本发送了任何非标题的输出(例如,使用 HTML 或 print()调用),那么PHP就必须先发送完所有的Header,然后终止 HTTPheader.而后继续发送主体数据.从这时开始,任何添加或修改Header信息的试图都是不允许的,并会发送上述的错误消息之一。

可以用以下办法来修改。

修改php.ini打开缓存(output_buffering),或者在程序中使用缓存函数ob_start(),ob_end_flush()等。原理是:output_buffering被启用时,在脚本发送输出时,PHP并不发送HTTPheader。相反,它将此输出通过管道(pipe)输入到动态增加的缓存中(只能在PHP4.0中使用,它具有中央化的输出机制)。你仍然可以修改/添加header,或者设置cookie,因为header实际上并没有发送。当全部脚本终止时,PHP将自动发送HTTP header到浏览器,然后再发送输出缓冲中的内容。

随机文章推荐
网站分类


注:如需转载本文,请注明出处(原文链接),谢谢。更多精彩内容,请进入简明现代魔法首页。

进入新博客
喜欢本文,就分享它吧
给我留言
您的名字:
您的邮件:
您的网站:


 

copyright © 2009 简明现代魔法    学习、分享、进步

power by Gonn 感谢所有关心和支持本站的朋友们