我注意到在我的网站源代码的HTML上面有两行空行。它看起来像这样:
<!-- Two empty lines here, StackOverflow won't let me post empty lines -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
HTML是用PHP生成的。我怎样才能知道输出是从哪里开始的?
我尝试在<html>
之后添加<?php header('...'); ?>
,希望触发"无法修改标题"之类的错误。输出从……行开始。"
如果您想获得文件名和开始输出的行号,您可以调用headers_sent()
函数和两个可选参数:
$sent = headers_sent($file, $line);
这两个变量$file
和$line
将包含调用函数后您要查找的信息。您不需要等待错误消息(但是,如果您没有看到任何错误消息,并且希望查明来源,则可能需要刷新输出(在许多地方))。所以要确保输出缓冲是禁用的。
它可能不会触发错误,因为到目前为止您打印的内容太短,并且在header调用之前仍然被缓冲。
尝试输出更多数据,例如:
echo str_repeat('a', 10000);
然后尝试输出一些标题。然后,您应该看到预期的PHP错误(假设您的错误报告设置已适当调整)。
我在Drupal上遇到了同样的问题(很多文件),我尝试了上面的几个答案,但没有任何结果。
最后,我找到了find方法(参见:搜索带有BOM的UTF-8文件的优雅方法?),它指出了一个愚蠢的错误:模块文件开头的空格:
find . -type f -name '*.module' -print0 | xargs -0r awk '/^ / {print FILENAME}{nextfile}'
find . -type f -name '*.php' -print0 | xargs -0r awk '/^ / {print FILENAME}{nextfile}'
find . -type f -name '*.inc' -print0 | xargs -0r awk '/^ / {print FILENAME}{nextfile}'
要直接回答您的问题,任何echo、print语句或任何将结果直接返回给标准输出的函数都将导致开始输出。另外,如果在<?php
标签开始前有任何HTML或文本或空行,这将导致输出开始。
您可以通过在条目文档的顶部<?php
标记下方添加ob_start()来直接修复此问题。并在文档的末尾添加ob_end_flush()。它看起来像这样。
将此添加到文档的最上方:
<?php
ob_start();
?>
将此添加到文档的最底部:
<?php
echo ob_end_flush();
?>
这允许您保留当前代码,并在代码中需要它们的地方输出头文件,而不会出现错误。
通过在PHP中放置这些行来显示错误:
error_reporting(E_ALL);
ini_set('display_errors','on');
这会触发报头错误!
它可能在PHP文件的末尾;您应该考虑删除结束PHP标记(?>
)来消除这个问题。
我刚刚遇到了隐藏bom的类似问题,但这也适用于空白行和其他虚假字符,所以我想在这里添加我的发现。
添加假标题(");在代码中调用是找到输出开始位置的最佳方法,但是……最有可能的是,PHP配置默认启用了output_buffering。看看这个
通过在脚本开头添加以下内容:
if (ob_get_level()) ob_end_clean();
将关闭输出缓冲,并使header()调用报错,并说明输出开始的位置。
如果您的代码中第一个<?php
上面有任何空行(假设您在文件的'顶部'有它)