-1

我知道这个问题之前已经发布过很多次了,但无论如何我都无法找到一个好的答案,因为该错误的行为并不完全符合其应有的行为。

你看,我有类似这样的代码:

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

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

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

4

3 回答 3

1

如果输出正在缓冲,并且最后一行menu.php填满缓冲区并将其冲下线,则会发生这种情况。

于 2013-07-21T11:45:19.447 回答
0

HTTPHeader 必须是首先发送的内容。并且脚本的任何输出(即使是单个字符或错误消息)都由 HTTP 标头处理。并且一旦开始发送内容,就无法发送附加标头。这是 HTTP 协议的基础知识。我会用你的代码解释它。

<?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 刷新横幅代码之前发送了标题。

于 2013-07-21T11:51:36.513 回答
0

任何修改标题的 PHP 都需要在任何其他页面数据之前,除非您打开了输出缓冲。当您输出任何内容时,标题会正确发送。HTML 代码、PHP 等。

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

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

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

于 2013-07-21T11:45:14.237 回答