简体   繁体   English

如何修复 PHP 中的“标头已发送”错误

[英]How to fix "Headers already sent" error in PHP

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.php on line 23警告:无法修改 header 信息 -第 23 行的 /some/file.php 中的( output 开始于 /some/file.php:12 已发送的标头

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?以及如何解决?

No output before sending headers!发送标头之前没有输出!

Functions that send/modify HTTP headers must be invoked before any output is made .必须在进行任何输出之前调用发送/修改 HTTP 标头的函数。 summary ⇊ Otherwise the call fails:摘要 ⇊否则调用失败:

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:无意:

  • Intentional:故意的:

    • print , echo and other functions producing output print , echo和其他产生输出的函数
    • Raw <html> sections prior <?php code. <?php代码之前的原始<html>部分。

Why does it happen?为什么会这样?

To understand why headers must be sent before output it's necessary to look at a typical HTTP response.要了解为什么必须在输出之前发送标头,有必要查看典型的HTTP响应。 PHP scripts mainly generate HTML content, but also pass a set of HTTP/CGI headers to the webserver: PHP 脚本主要生成 HTML 内容,但也会将一组 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 follows the headers.页面/输出始终跟随标题。 PHP has to pass the headers to the webserver first. PHP 必须首先将标头传递给网络服务器。 It can only do that once.它只能这样做一次。 After the double linebreak it can nevermore amend them.在双线断之后,它再也不能修改它们了。

When PHP receives the first output ( print , echo , <html> ) it will flush all collected headers.当 PHP 接收到第一个输出( printecho<html> )时,它将刷新所有收集的标题。 Afterward it can send all the output it wants.之后它可以发送它想要的所有输出。 But sending further HTTP headers is impossible then.但是那时发送更多的 HTTP 标头是不可能的。

How can you find out where the premature output occurred?如何找出过早输出发生的位置?

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警告:无法修改标头信息 - 标头已由第 100 行/www/usr2345/htdocs/index.php中的/www/usr2345/htdocs/auth.php:52发送的标头

Here "line 100" refers to the script where the header() invocation failed.这里的“第 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 .在这个例子中,它是auth.php52 That's where you had to look for premature output.这就是你必须寻找过早输出的地方。

Typical causes:典型原因:

  1. Print, echo打印,回显

    Intentional output from print and echo statements will terminate the opportunity to send HTTP headers. printecho语句的有意输出将终止发送 HTTP 标头的机会。 The application flow must be restructured to avoid that.必须重组应用程序流程以避免这种情况。 Use functions and templating schemes.使用函数和模板方案。 Ensure header() calls occur before messages are written out.确保在写出消息之前发生header()调用。

    Functions that produce output include产生输出的函数包括

    • print , echo , printf , vprintf printechovprintfprintf
    • trigger_error , ob_flush , ob_end_flush , var_dump , print_r trigger_error , ob_flush , ob_end_flush , var_dump , print_r
    • readfile , passthru , flush , imagepng , imagejpeg readfile , passthru , flush , imagepng , imagejpeg


    among others and user-defined functions.除其他外和用户定义的功能。

  2. Raw HTML areas原始 HTML 区域

    Unparsed HTML sections in a .php file are direct output as well. .php文件中未解析的 HTML 部分也是直接输出。 Script conditions that will trigger a header() call must be noted before any raw <html> blocks.必须在任何原始<html>块之前记录将触发header()调用的脚本条件。

     <!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.实际的输出逻辑和混合的 HTML 输出应该在最后。

  3. Whitespace before <?php for "script.php line 1 " warnings <?php之前的空格用于“script.php line 1 ”警告

    If the warning refers to output inline 1 , then it's mostly leading whitespace , text or HTML before the opening <?php token.如果警告是指输出内联1 ,那么它主要是开头<?php标记之前的前导空格、文本或 HTML。

     <?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 single linebreak after close tags. PHP 实际上在关闭标签后吃掉了一个换行符。 But it won't compensate multiple newlines or tabs or spaces shifted into such gaps.但它不会补偿多个换行符或制表符或空格转移到此类间隙中。

  4. UTF-8 BOM UTF-8 物料清单

    Linebreaks and spaces alone can be a problem.单独的换行符和空格可能是一个问题。 But there are also "invisible" character sequences that can cause this.但也有“不可见”的字符序列会导致这种情况。 Most famously the UTF-8 BOM (Byte-Order-Mark) which isn't displayed by most text editors.最著名的是大多数文本编辑器不显示的UTF-8 BOM (字节顺序标记) It's the byte sequence EF BB BF , which is optional and redundant for UTF-8 encoded documents.它是字节序列EF BB BF ,对于 UTF-8 编码的文档是可选的和冗余的。 PHP however has to treat it as raw output.然而,PHP 必须将其视为原始输出。 It may show up as the characters  in the output (if the client interprets the document as Latin-1) or similar "garbage".它可能在输出中显示为字符 (如果客户端将文档解释为Latin-1)或类似的“垃圾”。

    In particular graphical editors and Java-based IDEs are oblivious to its presence.尤其是图形编辑器和基于 Java 的 IDE 并没有注意到它的存在。 They don't visualize it (obliged by the Unicode standard).他们没有将其可视化(Unicode 标准要求)。 Most programmer and console editors however do:然而,大多数程序员和控制台编辑器会:

    joes 编辑器显示 UTF-8 BOM 占位符,MC 编辑器显示一个点

    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 .其他编辑器可能会在文件/设置菜单中识别它的存在(Windows 上的 Notepad++ 可以识别和解决问题),检查 BOM 存在的另一个选项是使用hexeditor On *nix systems hexdump is usually available, if not a graphical variant which simplifies auditing these and other issues:在 *nix 系统上,通常可以使用hexdump ,如果不是简化审计这些和其他问题的图形变体:

    显示 utf-8 bom 的 beav hexeditor

    An easy fix is to set the text editor to save files as "UTF-8 (no BOM)" or similar to such nomenclature.一个简单的解决方法是将文本编辑器设置为将文件保存为“UTF-8(无 BOM)”或类似于此类命名法。 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 or recode ).还有用于检查和重写文本文件的自动化工具( sed / awkrecode )。 For PHP specifically there's the phptags tag tidier .对于 PHP,特别是有phptags标签 titier 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:它将关闭和打开标签重写为长格式和短格式,还可以轻松修复前导和尾随空格、Unicode 和 UTF-x BOM 问题:

     phptags --whitespace *.php

    It's safe to use on a whole include or project directory.在整个包含或项目目录上使用是安全的。

  5. Whitespace after ?>后面的空格?>

    If the error source is mentioned as behind the closing ?> then this is where some whitespace or the raw text got written out.如果错误源在结尾?>后面提到,那么这就是一些空白或原始文本被写出的地方。 The PHP end marker does not terminate script execution at this point. PHP 结束标记此时不会终止脚本执行。 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.通常建议,尤其是对于新手,应该省略尾随的?> PHP 关闭标签。 This eschews a small portion of these cases.避开了这些案例的一小部分。 (Quite commonly include()d scripts are the culprit.) (通常include()d脚本是罪魁祸首。)

  6. Error source mentioned as "Unknown on line 0"错误源被提及为“第 0 行未知”

    It's typically a PHP extension or php.ini setting if no error source is concretized.如果没有具体化错误源,它通常是 PHP 扩展或 php.ini 设置。

    • It's occasionally the gzip stream encoding setting or the ob_gzhandler .有时是gzip流编码设置ob_gzhandler
    • But it could also be any doubly loaded extension= module generating an implicit PHP startup/warning message.但它也可能是任何双重加载的extension=模块生成隐式 PHP 启动/警告消息。

  7. Preceding error messages前面的错误消息

    If another PHP statement or expression causes a warning message or notice being printed out, that also counts as premature output.如果另一个 PHP 语句或表达式导致打印出警告消息或通知,这也算作过早输出。

    In this case you need to eschew the error, delay the statement execution, or suppress the message with eg isset() or @() - when either doesn't obstruct debugging later on.在这种情况下,您需要避免错误、延迟语句执行或使用例如isset()@()抑制消息 - 当两者都不会妨碍以后的调试时。

No error message没有错误信息

If you have error_reporting or display_errors disabled per php.ini , then no warning will show up.如果您根据php.ini禁用了error_reportingdisplay_errors ,则不会出现警告。 But ignoring errors won't make the problem go away.但是忽略错误不会让问题消失。 Headers still can't be sent after premature output.过早输出后仍然无法发送标头。

So when header("Location: ...") redirects silently fail it's very advisable to probe for warnings.因此,当header("Location: ...")重定向静默失败时,探查警告是非常明智的。 Reenable them with two simple commands atop the invocation script:使用调用脚本顶部的两个简单命令重新启用它们:

error_reporting(E_ALL);
ini_set("display_errors", 1);

Or set_error_handler("var_dump");set_error_handler("var_dump"); if all else fails.如果一切都失败了。

Speaking of redirect headers, you should often use an idiom like this for final code paths:说到重定向标头,您应该经常对最终代码路径使用这样的习惯用法:

exit(header("Location: /finished.html"));

Preferably even a utility function, which prints a user message in case of header() failures.最好是一个实用函数,它在header()失败的情况下打印用户消息。

Output buffering as a workaround输出缓冲作为一种解决方法

PHPs output buffering is a workaround to alleviate this issue. PHP输出缓冲是缓解此问题的一种解决方法。 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.它的实际目的是尽量减少到网络服务器的分块传输。

  1. The output_buffering= setting nevertheless can help. output_buffering=设置仍然可以提供帮助。 Configure it in the php.ini or via .htaccess or even .user.ini on modern FPM/FastCGI setups.在现代 FPM/FastCGI 设置中,在php.ini或通过.htaccess甚至.user.ini配置它。
    Enabling it will allow PHP to buffer output instead of passing it to the webserver instantly.启用它将允许 PHP 缓冲输出,而不是立即将其传递给网络服务器。 PHP thus can aggregate HTTP headers.因此 PHP 可以聚合 HTTP 标头。

  2. It can likewise be engaged with a call to ob_start();它同样可以通过调用ob_start(); atop the invocation script.在调用脚本之上。 Which however is less reliable for multiple reasons:然而,由于多种原因,它不太可靠:

    • Even if <?php ob_start(); ?>即使<?php ob_start(); ?> <?php ob_start(); ?> starts the first script, whitespace or a BOM might get shuffled before, rendering it ineffective . <?php ob_start(); ?>启动第一个脚本,空白或 BOM 可能会在之前被打乱, 使其无效

    • It can conceal whitespace for HTML output.它可以隐藏 HTML 输出的空格。 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 a further workaround.) ob_clean()作为进一步的解决方法。)

    • The buffer is limited in size, and can easily overrun when left to defaults.缓冲区的大小是有限的,并且在保留为默认值时很容易溢出。 And that's not a rare occurrence either, difficult to track down when it happens.这也不是罕见的事情,当它发生时很难追踪

Both approaches therefore may become unreliable - in particular when switching between development setups and/or production servers.因此,这两种方法都可能变得不可靠——尤其是在开发设置和/或生产服务器之间切换时。 This is why output buffering is widely considered just a crutch / strictly a workaround.这就是为什么输出缓冲被广泛认为只是一种拐杖/严格来说是一种解决方法。

See also the basic usage example in the manual, and for more pros and cons:另请参阅手册中的基本用法示例,了解更多优点和缺点:

But it worked on the other server!?但它在另一台服务器上工作!?

If you didn't get the headers warning before, then the output buffering php.ini setting has changed.如果您之前没有收到标头警告,则输出缓冲 php.ini 设置已更改。 It's likely unconfigured on the current/new server.它可能在当前/新服务器上未配置。

Checking with headers_sent()检查headers_sent()

You can always use headers_sent() to probe if it's still possible to... send headers.您始终可以使用headers_sent()来探测是否仍然可以...发送标头。 Which is useful to conditionally print info or apply other fallback logic.这对于有条件地打印信息或应用其他后备逻辑很有用。

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> tag HTML <meta>标签

    If your application is structurally hard to fix, then an easy (but somewhat unprofessional) way to allow redirects is injecting a HTML <meta> tag.如果您的应用程序在结构上难以修复,那么允许重定向的一种简单(但有点不专业)的方法是注入 HTML <meta>标记。 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.当在<head>部分之后使用时,这会导致 HTML 无效。 Most browsers still accept it.大多数浏览器仍然接受它。

  • JavaScript redirect JavaScript 重定向

    As alternative a JavaScript redirect can be used for page redirects:作为替代, JavaScript 重定向可用于页面重定向:

     <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.虽然这通常比<meta>解决方法更符合 HTML,但它会导致对支持 JavaScript 的客户端的依赖。

Both approaches however make acceptable fallbacks when genuine HTTP header() calls fail.然而,当真正的 HTTP header() 调用失败时,这两种方法都可以接受回退。 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_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. setcookie()session_start()都需要发送一个Set-Cookie: HTTP 头。 The same conditions therefore apply, and similar error messages will be generated for premature output situations.因此适用相同的条件,并且对于过早的输出情况将生成类似的错误消息。

(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更多链接

This error message gets triggered when anything is sent before you send HTTP headers (with setcookie or header ).在发送 HTTP 标头(使用setcookieheader )之前发送任何内容时会触发此错误消息。 Common reasons for outputting something before the HTTP headers are:在 HTTP 标头之前输出内容的常见原因是:

  • Accidental whitespace, often at the beginning or end of files, like this:意外的空格,通常在文件的开头或结尾,如下所示:

     <?php // Note the space before "<?php" ?>

To avoid this, simply leave out the closing ?> - it's not required anyways.为避免这种情况,只需省略关闭?> - 无论如何都不需要。

  • Byte order marks at the beginning of a php file. php 文件开头的字节顺序标记 Examine your php files with a hex editor to find out whether that's the case.使用十六进制编辑器检查您的 php 文件,看看是否是这种情况。 They should start with the bytes 3F 3C .它们应该以字节3F 3C开头。 You can safely remove the BOM EF BB BF from the start of files.您可以从文件开头安全地删除 BOM EF BB BF
  • Explicit output, such as calls to echo , printf , readfile , passthru , code before <?显式输出,例如调用echoprintfreadfilepassthru<? etc.等等
  • A warning outputted by php, if the display_errors php.ini property is set.如果设置了display_errors php.ini 属性,则 php 输出警告。 Instead of crashing on a programmer mistake, php silently fixes the error and emits a warning. php 不会因为程序员的错误而崩溃,而是默默地修复错误并发出警告。 While you can modify the display_errors or error_reporting configurations, you should rather fix the problem.虽然您可以修改display_errorserror_reporting配置,但您应该解决问题。
    Common reasons are accesses to undefined elements of an array (such as $_POST['input'] without using empty or isset 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).常见原因是访问数组的未定义元素(例如$_POST['input']而不使用emptyisset来测试输入是否设置),或使用未定义常量而不是字符串文字(如$_POST[input] ,请注意缺少的引号)。

Turning on output buffering should make the problem go away;打开输出缓冲应该可以解决问题; all output after the call to ob_start is buffered in memory until you release the buffer, eg 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.然而,虽然输出缓冲避免了这些问题,但您应该真正确定为什么您的应用程序在 HTTP 标头之前输出 HTTP 正文。 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.这就像在告诉来电者他的号码错误之前接听电话并讨论您的一天和天气一样。

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 before the start of the file or after the 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.注意:有时像 gedit(一个默认的 linux 编辑器)这样的 EDITOR(IDE) 会在保存文件上添加一个空行。 This should not happen.这不应该发生。 If you are using Linux.如果您使用的是 Linux。 you can use VI editor to remove space/lines after ?> at the end of the page.您可以使用 VI 编辑器删除页面末尾的 ?> 之后的空格/行。

Possible Solution 2: If this is not your case, then use ob_start to 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.这将打开输出缓冲,并且您的标题将在页面缓冲后创建。

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.我遇到了同样的问题,但我通过以上述方式编写标题位置解决了。

You do你做

printf ("Hi %s,</br />", $name);

before setting the cookies, which isn't allowed.在设置 cookie 之前,这是不允许的。 You can't send any output before the headers, not even a blank line.您不能在标题之前发送任何输出,甚至不能发送空行。

COMMON PROBLEMS:常见问题:

(copied from: source ) (复制自:来源

==================== =====================

1) there should not be any output (ie echo.. or HTML codes) before the header(.......); 1)header(.......);之前不应有任何输出(即echo..或 HTML 代码); command.命令。

2) remove any white-space (or newline ) before <?php and after ?> tags. 2)<?php?>标记之前删除所有空格(或换行符)。

3) GOLDEN RULE! 3)黄金法则! - check if that php file (and also, if you include other files) have UTF8 without BOM encoding (and not just UTF-8 ). - 检查该 php 文件(以及,如果您include其他文件)是否具有没有 BOM 编码的 UTF8 (而不仅仅是UTF-8 )。 That is problem in many cases (because UTF8 encoded file has something special character in the start of php file, which your text-editor doesnt show)!!!!!!!!!!!这在很多情况下都是问题(因为UTF8编码的文件在 php 文件的开头有一些特殊字符,您的文本编辑器没有显示)!!!!!!!!!!!!!!!

4) After header(...); 4)header(...); you must use exit;你必须使用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. 6)打开报错,发现错误。 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."例如,它可能是“警告:date_default_timezone_get():依赖系统的时区设置是不安全的”。 - 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.如果仍然有错误,请再次修复最顶层的错误。

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;

It is because of this line:这是因为这条线:

printf ("Hi %s,</br />", $name);

You should not print/echo anything before sending the headers.在发送标头之前,您不应打印/回显任何内容。

A simple tip: A simple space (or invisible special char) in your script, right before the very first <?php tag, can cause this !一个简单的提示:脚本中的一个简单空格(或不可见的特殊字符),就在第一个<?php标签之前,可能会导致这个! 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.尤其是当您在团队中工作并且有人使用“弱” IDE 或使用奇怪的文本编辑器在文件中乱七八糟时。

I have seen these things ;)我见过这些东西;)

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?现在,虽然这不是一个常见的场景,但如果您使用的是 MVC 框架,该框架会在将内容移交给控制器之前加载大量文件怎么办? This is not an uncommon scenario.这种情况并不少见。 Be prepare for this.为此做好准备。

From PSR-2 2.2 :PSR-2 2.2 开始:


  • All PHP files MUST use the Unix LF (linefeed) line ending .所有 PHP 文件必须使用Unix LF (linefeed) line ending
  • All PHP files MUST end with a single blank line .所有 PHP 文件必须以一个single blank line结束。
  • The closing ?> tag MUST be omitted from files containing only php关闭 ?> 标记必须从only php的文件中omitted

Believe me , following thse standards can save you a hell lot of hours from your life :)相信我,遵循这些标准可以为您节省大量时间:)

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.为了快速解决这个问题,我们通常会做的是重命名文件并在 LINUX 系统上创建一个新文件而不是重命名的文件,然后将内容复制到该文件中。 Many times this solve the issue as some of the files that were created in WIN once moved to the hosting cause this issue.很多时候这解决了这个问题,因为在 WIN 中创建的一些文件一旦移动到主机就会导致这个问题。

This fix is an easy fix for sites we manage by FTP and sometimes can save our new team members some time.对于我们通过 FTP 管理的站点,此修复是一个简单的修复,有时可以为我们的新团队成员节省一些时间。

Generally this error arise when we send header after echoing or printing.通常,当我们在回显或打印后发送标头时会出现此错误。 If this error arise on a specific page then make sure that page is not echoing anything before calling to start_session() .如果此错误出现在特定页面上,请确保该页面在调用start_session()之前没有回显任何内容。

Example of Unpredictable Error:不可预测的错误示例:

 <?php //a white-space before <?php also send for output and arise error
session_start();
session_regenerate_id();

//your page content

One more example:再举一个例子:

<?php
includes 'functions.php';
?> <!-- This new line will also arise error -->
<?php
session_start();
session_regenerate_id();

//your page content

Conclusion: Do not output any character before calling session_start() or header() functions not even a white-space or new-line结论:在调用session_start()header()函数之前不要输出任何字符,甚至是空格或换行符

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM