“标头已经从一个文件中的输出发送”错误,而不是另一个文件

时间:2013-07-21 11:41:02

标签: php html header

我知道此问题之前已多次发布,但无论如何我都找不到合适的答案,因为错误并不完全符合预期。

你知道,我的代码与此相似:

<?php
    include("banner.php");
    include("menu.php");
    print "<div class=\"wrapper\">";
        if(true) header("Location:index.php");
        else print "Hello World";
    print "</div>";
    include("footer.php");
?>

banner.php看起来像这样:

<div id=banner><a href=index.php><img src=img/banner.png></a></div>

menu.php看起来像这样:

<ul class="menu">
    <li class="dropdown">Menu
        <ul>
            <a href="test1.php?id=<?php print $id; ?>"><li>Item 1</li></a>
            <a href="test2.php?"><li>Item </li></a>
            <a href="test3.php"><li>Item 3</li></a>
            <a href="test4.php?id=<?php print $id; ?>"><li>Item 4</li></a>
        </ul>
    </li>
</ul>

请注意menu.php中有一些PHP元素。

如果我运行第一段代码,我会收到错误Warning: Cannot modify header information - headers already sent by (output started at /var/www/menu.php:10) in /var/www/test.php on line 5menu.php中的第10行是最后一行。如果我从代码中完全删除菜单,并离开banner.php,代码工作正常。我觉得这很令人困惑,因为banner.php也会提供输出,就像包含菜单后的print "<div class=\"wrapper\">";行一样。

我的问题很简单:为什么menu.php会触发错误,而banner.php却没有?

3 个答案:

答案 0 :(得分:1)

如果输出被缓冲,则会发生这种情况,并且menu.php的最后一行填满了缓冲区并将其刷新。

答案 1 :(得分:0)

任何修改标题的PHP都需要在任何其他页面数据之前,除非您有输出缓冲。输出ANYTHING后,标题会立即发送。 HTML代码,PHP,等等。

将PHP代码视为一个方面,Web服务器就是一个玻璃。让我们想象一下,我们将用HTML的输出来填充玻璃。一旦它获得第一次丢弃,标题就已经建立了它将要发送的内容。

您可以在PHP.ini中打开输出缓冲。

输出缓冲基本上就像一个量杯,你的PHP代码填满量杯,当它到达某个点时,它会被倒入玻璃杯(Web服务器)。虽然它正在构建,它仍然在PHP中我们可以访问它,这就是为什么我们能够修改我们没有给Web服务器任何东西的标头。但请注意,这会对服务器产生性能影响。你可能不会注意到它。

答案 2 :(得分:0)

HTTPHeader必须是第一个发送的东西。来自脚本的任何输出(即使它是单个字符或错误消息)都由HTTP标头继续。一旦内容发送开始,就无法发送附加标题。这是HTTP协议的基础知识。我会解释它WRT你的代码。

<?php
    include("banner.php");
    //The above line the banner output is sent.So does the HTTP Headers
    include("menu.php");
    print "<div class=\"wrapper\">";
        if(true) header("Location:index.php");
        //Because the Output is started in bannrd you cannot send additional headers.
        else print "Hello World";
    print "</div>";
    include("footer.php");
?>

如果在php.ini中启用了输出缓冲,则可能会发生不可预测的结果,因为headers永远不会被缓冲,内容只会被缓冲。在你的情况下,看起来你在php刷新横幅代码之前发送标题。