【问题标题】:php - track down premature headers leakphp - 追踪过早的标头泄漏
【发布时间】:2010-03-12 15:54:22
【问题描述】:

我在网站上使用 set_cookie()。添加一些功能后,我收到Warning: Cannot modify header information - headers already sent by... 错误。它引用的标头从哪里启动的行号就是 set_cookie() 所在的行!我检查了一下,它没有被调用两次。

如何追踪这些过早的标头?我查看了源代码,在错误消息开始之前没有看到任何杂散字符或任何东西(我正在使用xdebug,所以第一件事是一个
,我以为是我,但实际上是开始xdebug 消息)。我已经为额外的echo 获取了我的代码等等——什么都没有。

PHP 能告诉我标头何时何地开始吗?还是他们真的从 set_cookie 行开始,如果是这样,我是如何让自己陷入这种境地的,我该如何摆脱?


编辑:我不确定我可以粘贴代码——你只想要 set_cookie() 行吗?我以为标题在那之前就出来了。在此之前还有很多事情要实例化不同的类。而且我不认为我可以发布所有的课程和东西——你知道,专有信息;)


编辑:我已经去掉了所有终止分隔符(全部为?>s),并确保每个包含文件的第一个字符都是<?。这令人沮丧!在我进行这些最近的更改之前它正在工作:(((

另外,为什么headers_sent() 不起作用?

if ( headers_sent($filename, $linenum) ) { 
    echo "headers sent: $filename:$linenum."; 
}   
set_cookie(...); 

给予

headers sent: :0. 

【问题讨论】:

  • 能否给我们展示部分相关代码?
  • 您可以做的一件事是确保所有包含的文件中的 ?> 后面没有空格

标签: php header setcookie


【解决方案1】:

你可以使用headers_sent():

if (!headers_sent($filename, $linenum)) {
    set_cookie(/*...*/);
} else {
    echo "Headers already sent in $filename on line $linenum\n";
    exit;
}

【讨论】:

  • 就在set_cookie() 之前,if ( headers_sent($filename, $linenum) ) { echo "headers sent: filename:$linenum."; } 给出headers sent: :0. :(
  • 请确保(如其他人建议的那样)在您包含的所有 PHP 文件中,<?php 序列之前没有字符(甚至是空格或 BOM),?> 之后也没有字符。
【解决方案2】:

一种方法是从命令行运行脚本,并将 STDERR 重定向到 null。

这将向您显示发送到 STDOUT 的所有内容,即服务器将发送给客户端的所有内容。

希望,一旦你看到这个,就会清楚你的标题来自哪里。

【讨论】:

  • 谢谢,丹。如何进行重定向?实际的事件链取决于 POST 提交,所以我不确定我是否可以在命令行上触发它。
【解决方案3】:

除了使用headers_sent 来检测HTTP 标头是否已经发送,您还可以使用PHP’s output control 来缓冲输出。即使您已经完成了一些输出,这也允许您更改标题。

下面是一些通过调用ob_start 使用显式输出缓冲的示例:

ob_start();
echo 'foobar';
header('Content-Type: text/plain;charset=utf-8');

但请确保在完成任何输出之前调用ob_start。否则可能已经发送了 HTTP 标头。

【讨论】:

    【解决方案4】:

    你能粘贴代码吗?

    如果 [line where set_cookie is] 已经发送了它的标头,那么脚本中的错误会进一步出现。

    【讨论】:

      【解决方案5】:

      您确定在 set_cookie() 初始化之前没有调用任何包含文件吗?您是否有正在运行的会话,因为如果有,您可以在启动会话时在脚本中的同一点设置 cookie。

      【讨论】:

        【解决方案6】:

        如果在您的 set_cookie() 初始化之前甚至有一个空格,则会导致无法正确发送标头。也许尝试使用不同的编辑器并检查您的结果。

        【讨论】:

          【解决方案7】:

          我找到了!这是一个flush();,我在其中一页中独自躺着。令人惊讶的是,它没有正确地将$filename 和$linenumber 绑定到headers_sent()。

          【讨论】:

            猜你喜欢
            • 2018-02-24
            • 1970-01-01
            • 1970-01-01
            • 2012-07-01
            • 1970-01-01
            • 1970-01-01
            • 2011-02-15
            • 2012-12-21
            • 1970-01-01
            相关资源
            最近更新 更多