php 如何修复PHP中的“标题已发送”错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8028957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to fix "Headers already sent" error in PHP
提问by Moses89
When running my script, I am getting several errors like this:
运行我的脚本时,我收到了几个这样的错误:
Warning: Cannot modify header information - headers already sent by (output started at /some/file.php:12) in /some/file.phpon line 23
警告:不能更改头信息-已经(发送了头输出在/some/file.php:12开始)在/some/file.php上线23
The lines mentioned in the error messages contain header()
and setcookie()
calls.
错误消息中提到的行包含header()
和setcookie()
调用。
What could be the reason for this? And how to fix it?
这可能是什么原因?以及如何修复它?
回答by mario
No output before sending headers!
发送标头之前没有输出!
Functions that send/modify HTTP headers must be invoked before any output is made. summary ?Otherwise the call fails:
必须在进行任何输出之前调用发送/修改 HTTP 标头的函数。 summary ?否则调用失败:
Warning: Cannot modify header information - headers already sent (output started at script:line)
警告:无法修改标头信息 - 标头已发送(输出从script:line开始)
Some functions modifying the HTTP header are:
一些修改 HTTP 标头的函数是:
Output can be:
输出可以是:
Unintentional:
- Whitespace before
<?php
or after?>
- The UTF-8 Byte Order Markspecifically
- Previous error messages or notices
- Whitespace before
无意:
- 之前
<?php
或之后的空格?>
- 在UTF-8字节顺序标记明确
- 以前的错误消息或通知
- 之前
Intentional:
print
,echo
and other functions producing output- Raw
<html>
sections prior<?php
code.
故意的:
print
,echo
和其他产生输出的函数- 原始
<html>
部分先验<?php
代码。
Why does it happen?
为什么会发生?
To understand why headers must be sent before output it's necessary to look at a typical HTTPresponse. PHP scripts mainly generate HTML content, but also pass a set of HTTP/CGI headers to the webserver:
要了解为什么必须在输出之前发送标头,有必要查看典型的HTTP响应。PHP 脚本主要生成 HTML 内容,但也会向 Web 服务器传递一组 HTTP/CGI 标头:
HTTP/1.1 200 OK
Powered-By: PHP/5.3.7
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
<html><head><title>PHP page output page</title></head>
<body><h1>Content</h1> <p>Some more output follows...</p>
and <a href="/"> <img src=internal-icon-delayed> </a>
The page/output always followsthe headers. PHP has to pass the headers to the webserver first. It can only do that once. After the double linebreak it can nevermore amend them.
页面/输出总是跟在标题后面。PHP 必须首先将标头传递给网络服务器。它只能这样做一次。在双换行之后,它再也不能修改它们了。
When PHP receives the first output (print
, echo
, <html>
) it will
flushall collected headers. Afterwards it can send all the output
it wants. But sending further HTTP headers is impossible then.
当 PHP 收到第一个输出 ( print
, echo
, <html>
) 时,它会
刷新所有收集的标头。之后它可以发送它想要的所有输出。但是发送更多的 HTTP 标头是不可能的。
How can you find out where the premature output occured?
您如何找出过早输出发生的位置?
The header()
warning contains all relevant information to
locate the problem cause:
该header()
警告包含用于定位问题原因的所有相关信息:
Warning: Cannot modify header information - headers already sent by (output started at/www/usr2345/htdocs/auth.php:52) in /www/usr2345/htdocs/index.php on line 100
警告:不能更改头信息-头已经发出 (输出开始在/ WWW / usr2345 / htdocs中/ auth.php:52)在第100行/www/usr2345/htdocs/index.php
Here "line 100" refers to the script where the header()
invocationfailed.
这里的“第 100 行”指的是header()
调用失败的脚本。
The "output started at" note within the parenthesis is more significant.
It denominates the source of previous output. In this example it's auth.php
and line 52
. That's where you had to look for premature output.
括号内的“输出开始于”注释更重要。它指定了先前输出的来源。在这个例子中,它是auth.php
和line52
。这就是您必须寻找过早输出的地方。
Typical causes:
典型原因:
Print, echo
Intentional output from
print
andecho
statements will terminate the opportunity to send HTTP headers. The application flow must be restructured to avoid that. Use functionsand templating schemes. Ensureheader()
calls occur beforemessages are written out.Functions that produce output include
print
,echo
,printf
,vprintf
trigger_error
,ob_flush
,ob_end_flush
,var_dump
,print_r
readfile
,passthru
,flush
,imagepng
,imagejpeg
among others and user-defined functions.Raw HTML areas
Unparsed HTML sections in a
.php
file are direct output as well. Script conditions that will trigger aheader()
call must be noted before anyraw<html>
blocks.<!DOCTYPE html> <?php // Too late for headers already.
Use a templating scheme to separate processing from output logic.
- Place form processing code atop scripts.
- Use temporary string variables to defer messages.
- The actual output logic and intermixed HTML output should follow last.
Whitespace before
<?php
for "script.php line 1" warningsIf the warning refers to output in line
1
, then it's mostly leading whitespace, text or HTML before the opening<?php
token.<?php # There's a SINGLE space/newline before <? - Which already seals it.
Similarly it can occur for appended scripts or script sections:
?> <?php
PHP actually eats up a singlelinebreak after close tags. But it won't compensate multiple newlines or tabs or spaces shifted into such gaps.
UTF-8 BOM
Linebreaks and spaces alone can be a problem. But there are also "invisible" character sequences which can cause this. Most famously the UTF-8 BOM(Byte-Order-Mark)which isn't displayed by most text editors. It's the byte sequence
EF BB BF
, which is optional and redundant for UTF-8 encoded documents. PHP however has to treat it as raw output. It may show up as the characters???
in the output (if the client interprets the document as Latin-1) or similar "garbage".In particular graphical editors and Java based IDEs are oblivious to its presence. They don't visualize it (obliged by the Unicode standard). Most programmer and console editors however do:
There it's easy to recognize the problem early on. Other editors may identify its presence in a file/settings menu (Notepad++ on Windows can identify and remedy the problem), Another option to inspect the BOMs presence is resorting to an hexeditor. On *nix systems
hexdump
is usually available, if not a graphical variant which simplifies auditing these and other issues:An easy fix is to set the text editor to save files as "UTF-8 (no BOM)" or similar such nomenclature. Often newcomers otherwise resort to creating new files and just copy&pasting the previous code back in.
Correction utilities
There are also automated tools to examine and rewrite text files (
sed
/awk
orrecode
). For PHP specifically there's thephptags
tag tidier. It rewrites close and open tags into long and short forms, but also easily fixes leading and trailing whitespace, Unicode and UTF-x BOM issues:phptags --whitespace *.php
It's sane to use on a whole include or project directory.
Whitespace after
?>
If the error source is mentioned as behind the closing
?>
then this is where some whitespace or raw text got written out. The PHP end marker does not terminate script executation at this point. Any text/space characters after it will be written out as page content still.It's commonly advised, in particular to newcomers, that trailing
?>
PHP close tags should be omitted. This eschewsa small portion of these cases. (Quite commonlyinclude()d
scripts are the culprit.)Error source mentioned as "Unknown on line 0"
It's typically a PHP extension or php.ini setting if no error source is concretized.
- It's occasionally the
gzip
stream encoding setting or theob_gzhandler
. - But it could also be any doubly loaded
extension=
module generating an implicit PHP startup/warning message.
- It's occasionally the
Preceding error messages
If another PHP statement or expression causes a warning message or notice being printeded out, that also counts as premature output.
In this case you need to eschew the error, delay the statement execution, or suppress the message with e.g.
isset()
or@()
- when either doesn't obstruct debugging later on.
打印,回声
print
和echo
语句的有意输出将终止发送 HTTP 标头的机会。必须重构应用程序流程以避免这种情况。使用函数和模板方案。确保在写出消息之前header()
发生呼叫。产生输出的函数包括
print
,echo
,printf
,vprintf
trigger_error
,ob_flush
,ob_end_flush
,var_dump
,print_r
readfile
,passthru
,flush
,imagepng
,imagejpeg
其中包括和用户定义的函数。原始 HTML 区域
.php
文件中未解析的 HTML 部分也是直接输出。header()
必须在任何原始<html>
块之前记录将触发调用的脚本条件。<!DOCTYPE html> <?php // Too late for headers already.
使用模板方案将处理与输出逻辑分开。
- 将表单处理代码置于脚本之上。
- 使用临时字符串变量来延迟消息。
- 实际的输出逻辑和混合的 HTML 输出应该在最后。
<?php
“script.php line 1”警告前的空格如果警告指的是 line 中的输出
1
,那么它主要是在开始标记之前的前导空格、文本或 HTML<?php
。<?php # There's a SINGLE space/newline before <? - Which already seals it.
同样,附加脚本或脚本部分也可能发生这种情况:
?> <?php
PHP实际上吃了一个单一的关闭标签后断行。但它不会补偿移动到此类间隙中的多个换行符或制表符或空格。
UTF-8 物料清单
单独的换行符和空格可能是一个问题。但也有可能导致这种情况的“不可见”字符序列。最著名的 是大多数文本编辑器不显示的 UTF-8 BOM(字节顺序标记)。它是字节序列
EF BB BF
,对于 UTF-8 编码的文档来说是可选的和冗余的。然而,PHP 必须将其视为原始输出。它可能会显示为???
输出中的字符(如果客户端将文档解释为 Latin-1)或类似的“垃圾”。特别是图形编辑器和基于 Java 的 IDE 没有注意到它的存在。他们没有将它可视化(Unicode 标准要求)。然而,大多数程序员和控制台编辑器都这样做:
在那里很容易及早发现问题。其他编辑器可能会在文件/设置菜单中识别它的存在(Windows 上的 Notepad++ 可以识别并 解决问题),检查 BOM 存在的另一种选择是求助于hexeditor。在 *nix 系统
hexdump
上通常可用,如果不是图形变体,它可以简化审核这些和其他问题:一个简单的解决方法是将文本编辑器设置为将文件保存为“UTF-8(无 BOM)”或类似的命名法。否则,新手通常会求助于创建新文件,然后将之前的代码复制并粘贴回去。
校正实用程序
还有一些自动化工具可以检查和重写文本文件(
sed
/awk
或recode
)。特别是对于 PHP,有phptags
标签 tiier。它将关闭和打开标签重写为长短格式,但也可以轻松修复前导和尾随空格、Unicode 和 UTF-x BOM 问题:phptags --whitespace *.php
在整个包含或项目目录上使用是明智的。
之后的空格
?>
如果错误源在结尾
?>
被提及, 那么这就是写出一些空白或原始文本的地方。此时 PHP 结束标记不会终止脚本执行。它之后的任何文本/空格字符仍将作为页面内容写出。通常建议,特别是对于新手,
?>
应该省略尾随的PHP 结束标记。这避免了这些案例中的一小部分。(通常include()d
脚本是罪魁祸首。)错误来源被提及为“第 0 行未知”
如果没有具体化错误源,它通常是 PHP 扩展或 php.ini 设置。
- 偶尔是
gzip
流编码设置 或ob_gzhandler
. - 但它也可以是任何
extension=
生成隐式 PHP 启动/警告消息的双重加载模块。
- 偶尔是
之前的错误消息
如果另一个 PHP 语句或表达式导致打印出警告消息或通知,这也算作过早输出。
在这种情况下,您需要避开错误,延迟语句执行,或使用 eg
isset()
或@()
-抑制消息, 当两者都不会妨碍以后的调试时。
No error message
没有错误信息
If you have error_reporting
or display_errors
disabled per php.ini
,
then no warning will show up. But ignoring errors won't make the problem go
away. Headers still can't be sent after premature output.
如果您有error_reporting
或display_errors
禁用 per php.ini
,则不会显示任何警告。但是忽略错误不会使问题消失。过早输出后仍然无法发送标头。
So when header("Location: ...")
redirects silently fail it's very
advisable to probe for warnings. Reenable them with two simple commands
atop the invocation script:
因此,当header("Location: ...")
重定向以静默方式失败时,最好探测警告。使用调用脚本顶部的两个简单命令重新启用它们:
error_reporting(E_ALL);
ini_set("display_errors", 1);
Or set_error_handler("var_dump");
if all else fails.
或者set_error_handler("var_dump");
如果所有其他方法都失败了。
Speaking of redirect headers, you should often use an idiom like this for final code paths:
说到重定向标头,您应该经常对最终代码路径使用这样的习惯用法:
exit(header("Location: /finished.html"));
Preferrably even a utility function, which prints a user message
in case of header()
failures.
最好是一个实用函数,它会在header()
出现故障时打印用户消息。
Output buffering as workaround
输出缓冲作为解决方法
PHPs output bufferingis a workaround to alleviate this issue. It often works reliably, but shouldn't substitute for proper application structuring and separating output from control logic. Its actual purpose is minimizing chunked transfers to the webserver.
PHP 的输出缓冲是缓解此问题的一种解决方法。它通常可以可靠地工作,但不应替代适当的应用程序结构和将输出与控制逻辑分离。它的实际目的是最小化到网络服务器的分块传输。
The
output_buffering=
setting nevertheless can help. Configure it in the php.inior via .htaccessor even .user.inion modern FPM/FastCGI setups.
Enabling it will allow PHP to buffer output instead of passing it to the webserver instantly. PHP thus can aggregate HTTP headers.It can likewise be engaged with a call to
ob_start();
atop the invocation script. Which however is less reliable for multiple reasons:Even if
<?php ob_start(); ?>
starts the first script, whitespace or a BOM might get shuffled before, rendering it ineffective.It can conceal whitespace for HTML output. But as soon as the application logic attempts to send binary content (a generated image for example), the buffered extraneous output becomes a problem. (Necessitating
ob_clean()
as furher workaround.)The buffer is limited in size, and can easily overrun when left to defaults. And that's not a rare occurence either, difficult to track downwhen it happens.
output_buffering=
尽管如此,该设置还是有帮助的。在现代 FPM/FastCGI 设置中,在php.ini或通过.htaccess甚至.user.ini配置它。
启用它将允许 PHP 缓冲输出而不是立即将其传递到网络服务器。PHP 因此可以聚合 HTTP 标头。它同样可以参与
ob_start();
对调用脚本顶部的调用。然而,由于多种原因,它不太可靠:
Both approaches therefore may become unreliable - in particular when switching between development setups and/or production servers. Which is why output buffering is widely considered just a crutch / strictly a workaround.
因此,这两种方法都可能变得不可靠 - 特别是在开发设置和/或生产服务器之间切换时。这就是为什么输出缓冲被广泛认为只是一个拐杖/严格的解决方法。
See also the basic usage examplein the manual, and for more pros and cons:
另请参阅 手册中的基本用法示例,以及更多优缺点:
- What is output buffering?
- Why use output buffering in PHP?
- Is using output buffering considered a bad practice?
- Use case for output buffering as the correct solution to "headers already sent"
But it worked on the other server!?
但它在另一台服务器上工作!?
If you didn't get the headers warning before, then the output buffering php.ini settinghas changed. It's likely unconfigured on the current/new server.
如果您之前没有收到标题警告,则输出缓冲 php.ini 设置已更改。它可能未在当前/新服务器上配置。
Checking with headers_sent()
检查与 headers_sent()
You can always use headers_sent()
to probe if
it's still possible to... send headers. Which is useful to conditionally print
an info or apply other fallback logic.
您始终可以使用headers_sent()
来探测是否仍然可以...发送标头。这对于有条件地打印信息或应用其他回退逻辑很有用。
if (headers_sent()) {
die("Redirect failed. Please click on this link: <a href=...>");
}
else{
exit(header("Location: /user.php"));
}
Useful fallback workarounds are:
有用的回退解决方法是:
HTML
<meta>
tagIf your application is structurally hard to fix, then an easy (but somewhat unprofessional) way to allow redirects is injecting a HTML
<meta>
tag. A redirect can be achieved with:<meta http-equiv="Location" content="http://example.com/">
Or with a short delay:
<meta http-equiv="Refresh" content="2; url=../target.html">
This leads to non-valid HTML when utilized past the
<head>
section. Most browsers still accept it.JavaScript redirect
As alternative a JavaScript redirectcan be used for page redirects:
<script> location.replace("target.html"); </script>
While this is often more HTML compliant than the
<meta>
workaround, it incurs a reliance on JavaScript-capable clients.
HTML
<meta>
标签如果您的应用程序在结构上难以修复,那么允许重定向的一种简单(但有点不专业)的方法是注入 HTML
<meta>
标记。可以通过以下方式实现重定向:<meta http-equiv="Location" content="http://example.com/">
或者有一个短暂的延迟:
<meta http-equiv="Refresh" content="2; url=../target.html">
这会导致在超过该
<head>
部分时使用无效的 HTML 。大多数浏览器仍然接受它。JavaScript 重定向
作为替代,JavaScript 重定向可用于页面重定向:
<script> location.replace("target.html"); </script>
虽然这通常比
<meta>
变通方法更符合 HTML 标准,但它会导致对支持 JavaScript 的客户端的依赖。
Both approaches however make acceptable fallbacks when genuine HTTP header() calls fail. Ideally you'd always combine this with a user-friendly message and clickable link as last resort. (Which for instance is what the http_redirect()PECL extension does.)
然而,当真正的 HTTP header() 调用失败时,这两种方法都可以接受。理想情况下,您总是将此与用户友好的消息和可点击的链接结合起来作为最后的手段。(例如,这是http_redirect()PECL 扩展所做的。)
Why setcookie()
and session_start()
are also affected
为什么setcookie()
并且session_start()
也受到影响
Both setcookie()
and session_start()
need to send a Set-Cookie:
HTTP header.
The same conditions therefore apply, and similar error messages will be generated
for premature output situations.
双方setcookie()
并session_start()
需要发送一个Set-Cookie:
HTTP标头。因此,同样的条件适用,并且对于过早的输出情况将生成类似的错误消息。
(Of course they're furthermore affected by disabled cookies in the browser, or even proxy issues. The session functionality obviously also depends on free disk space and other php.ini settings, etc.)
(当然,它们还受到浏览器中禁用 cookie 甚至代理问题的影响。会话功能显然还取决于可用磁盘空间和其他 php.ini 设置等。)
Further links
更多链接
- Google provides a lengthy list of similar discussions.
- And of course many specific caseshave been covered on Stack Overflow as well.
- The Wordpress FAQ explains How do I solve the Headers already sent warning problem?in a generic manner.
- Adobe Community: PHP development: why redirects don't work (headers already sent)
- Nucleus FAQ: What does "page headers already sent" mean?
- One of the more thorough explanations is HTTP Headers and the PHP header() Function - A tutorial by NicholasSolutions(Internet Archive link). It covers HTTP in detail and gives a few guidelines for rewriting scripts.
- Google 提供了一份冗长的类似讨论列表。
- 当然,Stack Overflow 上也涵盖了许多特定情况。
- Wordpress 常见问题解答解释了如何解决标题已发送警告问题?以一种通用的方式。
- Adobe 社区:PHP 开发:为什么重定向不起作用(已发送标头)
- Nucleus 常见问题解答:“页眉已发送”是什么意思?
- 更详尽的解释之一是HTTP 标头和 PHP header() 函数 - NicholasSolutions 的教程(互联网档案链接)。它详细介绍了 HTTP 并提供了一些重写脚本的指南。
回答by phihag
This error message gets triggered when anythingis sent before you send HTTP headers (with setcookie
or header
). Common reasons for outputting something before the HTTP headers are:
在您发送 HTTP 标头(带有或)之前发送任何内容时会触发此错误消息。在 HTTP 标头之前输出某些内容的常见原因是:setcookie
header
Accidental whitespace, often at the beginning or end of files, like this:
<?php // Note the space before "<?php" ?>
意外的空格,通常在文件的开头或结尾,如下所示:
<?php // Note the space before "<?php" ?>
To avoid this, simply leave out the closing ?>
- it's not required anyways.
为避免这种情况,只需省略结束语?>
- 无论如何都不需要。
- Byte order marksat the beginning of a php file. Examine your php files with a hex editor to find out whether that's the case. They should start with the bytes
3F 3C
. You can safely remove the BOMEF BB BF
from the start of files. - Explicit output, such as calls to
echo
,printf
,readfile
,passthru
, code before<?
etc. - A warning outputted by php, if the
display_errors
php.ini property is set. Instead of crashing on a programmer mistake, php silently fixes the error and emits a warning. While you can modify thedisplay_errors
or error_reportingconfigurations, you should rather fix the problem.
Common reasons are accesses to undefined elements of an array (such as$_POST['input']
without usingempty
orisset
to test whether the input is set), or using an undefined constant instead of a string literal (as in$_POST[input]
, note the missing quotes).
- php 文件开头的字节顺序标记。使用十六进制编辑器检查您的 php 文件,以确定是否是这种情况。它们应该从 bytes 开始
3F 3C
。您可以EF BB BF
从文件的开头安全地删除 BOM 。 - 显式输出,例如调用
echo
、printf
、readfile
、passthru
、 之前的代码<?
等。 - 如果
display_errors
设置了php.ini 属性,则 php 输出的警告。php 不会因为程序员的错误而崩溃,而是默默地修复错误并发出警告。虽然您可以修改display_errors
或error_reporting配置,但您更应该解决问题。
常见的原因是访问数组的未定义元素(例如$_POST['input']
不使用empty
或isset
测试输入是否已设置),或使用未定义的常量而不是字符串文字(如在 中$_POST[input]
,请注意缺少的引号)。
Turning on output bufferingshould make the problem go away; all output after the call to ob_start
is buffered in memory until you release the buffer, e.g. with ob_end_flush
.
打开输出缓冲应该会使问题消失;调用后的所有输出ob_start
都缓冲在内存中,直到您释放缓冲区,例如使用ob_end_flush
.
However, while output buffering avoids the issues, you should really determine why your application outputs an HTTP body before the HTTP header. That'd be like taking a phone call and discussing your day and the weather before telling the caller that he's got the wrong number.
然而,虽然输出缓冲避免了这些问题,但您应该真正确定为什么您的应用程序在 HTTP 标头之前输出 HTTP 正文。这就像在告诉来电者他接错号码之前接听电话并讨论您的一天和天气。
回答by Manish Shrivastava
I got this error many times before, and I am certain all PHP programmer got this error at least once before.
我以前多次遇到此错误,而且我确信所有 PHP 程序员之前都至少遇到过一次此错误。
Possible Solution 1
可能的解决方案 1
This error may have been caused by the blank spaces beforethe start of the file or afterthe end of the file.These blank spaces should not be here.
此错误可能是由文件开始前或文件结束后的空格引起的。这些空格不应该出现在此处。
ex) THERE SHOULD BE NO BLANK SPACES HERE
ex) 这里不应该有空格
echo "your code here";
?>
THERE SHOULD BE NO BLANK SPACES HERE
Check all files associated with file that causes this error.
检查与导致此错误的文件关联的所有文件。
Note:Sometimes EDITOR(IDE) like gedit (a default linux editor) add one blank line on save file. This should not happen. If you are using Linux. you can use VI editor to remove space/lines after ?> at the end of the page.
注意:有时 EDITOR(IDE) 像 gedit(默认的 linux 编辑器)会在保存文件中添加一个空行。这不应该发生。如果您使用的是 Linux。您可以使用 VI 编辑器删除页面末尾的 ?> 之后的空格/行。
Possible Solution 2:If this is not your case, then use ob_startto output buffering:
可能的解决方案 2:如果这不是您的情况,则使用ob_start输出缓冲:
<?php
ob_start();
// code
ob_end_flush();
?>
This will turn output buffering on and your headers will be created after the page is buffered.
这将打开输出缓冲,并且您的标题将在页面缓冲后创建。
回答by Ipsita Rout
Instead of the below line
而不是下面的行
//header("Location:".ADMIN_URL."/index.php");
write
写
echo("<script>location.href = '".ADMIN_URL."/index.php?msg=$msg';</script>");
or
或者
?><script><?php echo("location.href = '".ADMIN_URL."/index.php?msg=$msg';");?></script><?php
It'll definitely solve your problem. I faced the same problem but I solved through writing header location in the above way.
绝对能解决你的问题。我遇到了同样的问题,但我通过以上述方式写入标头位置解决了。
回答by Seth Carnegie
You do
你做
printf ("Hi %s,</br />", $name);
before setting the cookies, which isn't allowed. You can't send any output before the headers, not even a blank line.
在设置 cookie 之前,这是不允许的。您不能在标题之前发送任何输出,甚至不能发送空行。
回答by Sarfraz
It is because of this line:
这是因为这一行:
printf ("Hi %s,</br />", $name);
You should not print/echoanything before sending the headers.
在发送标题之前,您不应该打印/回显任何内容。
回答by Jorn
COMMON PROBLEMS:
常见问题:
(copied from: source)
(复制自:来源)
====================
====================
1)there should not be any output (i.e. echo..
or HTML codes) before the header(.......);
command.
1)命令echo..
前不应有任何输出(即或 HTML 代码)header(.......);
。
2)remove any white-space(or newline) before <?php
and after ?>
tags.
2)除去任何空白(或换行之前)<?php
和后?>
标记。
3)GOLDEN RULE!- check if that php file (and also, if you include
other files) have UTF8 without BOMencoding (and not just UTF-8). That is problem in many cases (because UTF8encoded file has something special character in the start of php file, which your text-editor doesnt show)!!!!!!!!!!!
3)黄金法则!- 检查该 php 文件(以及include
其他文件)是否具有没有 BOM编码的UTF8(而不仅仅是UTF-8)。这在很多情况下都是问题(因为UTF8编码的文件在 php 文件的开头有一些特殊字符,你的文本编辑器没有显示)!!!!!!!!!!!!
4)After header(...);
you must use exit;
4)在header(...);
你必须使用之后exit;
5)always use 301 or 302 reference:
5)始终使用 301 或 302 引用:
header("location: http://example.com", true, 301 ); exit;
6)Turn on error reporting, and find the error.Your error may be caused by a function that is not working. When you turn on error reporting, you should always fix top-most error first. For example, it might be "Warning: date_default_timezone_get(): It is not safe to rely on the system's timezone settings." - then farther on down you may see "headers not sent" error. After fixing top-most (1st) error, re-load your page. If you still have errors, then again fix the top-most error.
6)开启报错,查找错误。您的错误可能是由无法正常工作的功能引起的。当您打开错误报告时,您应该始终首先修复最顶层的错误。例如,它可能是“警告:date_default_timezone_get():依赖系统的时区设置是不安全的。” - 再往下走,您可能会看到“未发送标头”错误。修复最顶部(第一个)错误后,重新加载您的页面。如果您仍然有错误,请再次修复最上面的错误。
7)If none of above helps, use JAVSCRIPT redirection(however, strongly non-recommended method), may be the last chance in custom cases...:
7)如果以上都没有帮助,请使用 JAVSCRIPT 重定向(但是,强烈不推荐的方法),可能是自定义情况下的最后机会...:
echo "<script type='text/javascript'>window.top.location='http://website.com/';</script>"; exit;
回答by Sliq
A simple tip: A simple space (or invisible special char) in your script, right before the very first <?php
tag, can cause this !
Especially when you are working in a team and somebody is using a "weak" IDE or has messed around in the files with strange text editors.
一个简单的提示:脚本中的一个简单的空格(或不可见的特殊字符),就在第一个<?php
标签之前,可能会导致这种情况!特别是当您在团队中工作并且有人使用“弱”IDE 或使用奇怪的文本编辑器在文件中乱搞时。
I have seen these things ;)
我见过这些东西;)
回答by MD. Sahib Bin Mahboob
Another bad practice can invoke this problem which is not stated yet.
另一个不好的做法可能会引发这个尚未说明的问题。
See this code snippet:
请参阅此代码片段:
<?php
include('a_important_file.php'); //really really really bad practise
header("Location:A location");
?>
Things are okay,right?
事情没问题吧?
What if "a_important_file.php" is this:
如果“a_important_file.php”是这样的怎么办:
<?php
//some php code
//another line of php code
//no line above is generating any output
?>
----------This is the end of the an_important_file-------------------
This will not work? Why?Because already a new line is generated.
这行不通?为什么?因为已经生成了一个新行。
Now,though this is not a common scenario what if you are using a MVC framework which loads a lots of file before handover things to your controller? This is not an uncommon scenario. Be prepare for this.
现在,虽然这不是一个常见的场景,如果您使用 MVC 框架在将东西移交给您的控制器之前加载大量文件怎么办?这种情况并不少见。为此做好准备。
From PSR-2 2.2 :
- All PHP files MUST use the
Unix LF (linefeed) line ending
. - All PHP files MUST end with a
single blank line
. - The closing ?> tag MUST be
omitted
from files containingonly php
- 所有 PHP 文件都必须使用
Unix LF (linefeed) line ending
. - 所有 PHP 文件必须以
single blank line
. - 结束 ?> 标签必须
omitted
来自包含only php
Believe me , following thse standards can save you a hell lot of hours from your life :)
相信我,遵循这些标准可以为您节省大量时间:)
回答by Lupin
Sometimes when the dev process has both WIN work stations and LINUX systems (hosting) and in the code you do not see any output before the related line, it could be the formatting of the file and the lack of Unix LF (linefeed)line ending.
有时,当开发进程同时具有 WIN 工作站和 LINUX 系统(托管)并且在代码中您在相关行之前没有看到任何输出时,可能是文件格式和缺少Unix LF(换行)行结束.
What we usually do in order to quickly fix this, is rename the file and on the LINUX system create a new file instead of the renamed one, and then copy the content into that. Many times this solve the issue as some of the files that were created in WIN once moved to the hosting cause this issue.
为了快速解决这个问题,我们通常会重命名文件,然后在 LINUX 系统上创建一个新文件而不是重命名的文件,然后将内容复制到该文件中。很多时候这解决了这个问题,因为在 WIN 中创建的一些文件一旦移动到主机就会导致这个问题。
This fix is an easy fix for sites we manage by FTP and sometimes can save our new team members some time.
对于我们通过 FTP 管理的站点,此修复是一个简单的修复,有时可以为我们的新团队成员节省一些时间。