本文介绍了如何修复“标题已发送"

问题描述

.它将关闭和打开标签重写为长短形式,但也很容易修复了前导和尾随空格、Unicode 和 UTF-x BOM 问题:

在整个包含或项目目录中使用是安全的.

  • ?>

    后的空格

    如果在后面提到了错误源那么这是写出一些空白或原始文本的地方.此时

    通常建议,特别是对于新手,尾随 ?> 避免了这些案例中的一小部分.(通常 include()d 脚本是罪魁祸首.)

  • 提到的错误源为第 0 行未知"

    如果没有错误源,通常是

    • 偶尔是 gzip 流编码设置.
    • 但它也可以是任何双重加载的 extension= 模块生成隐式
  • 之前的错误消息

    如果另一个

    在这种情况下,您需要避开错误,延迟语句执行,或使用例如抑制消息 或 -当两者都不会妨碍以后的调试时.

  • 没有错误信息

    如果您根据 禁用了 error_reportingdisplay_errors,那么不会出现警告.但是忽略错误不会使问题解决离开.过早输出后仍然无法发送Header.

    因此,当 header("Location: ...") 重定向以静默方式失败时,这是非常建议探测警告.使用两个简单的命令重新启用它们在调用脚本之上:

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

    或者 set_error_handler("var_dump"); 如果其他方法都失败了.

    说到重定向头,你应该经常使用这样的习惯用法这是最终代码路径:

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

    最好是一个实用函数,它打印用户消息在 header() 失败的情况下.

    输出缓冲作为一种解决方法

    输出缓冲是缓解此问题的解决方法.它通常工作可靠,但不应该替代适当的应用程序结构并将输出与控制分离逻辑.它的实际目的是尽量减少到网络服务器的分块传输.

    1. 尽管如此,设置还是有帮助的.在 甚至 上现代 FPM/FastCGI 设置.
      启用它将允许

    2. 它同样可以调用ob_start();在调用脚本之上.然而,由于多种原因,它不太可靠:

      • 即使 .

      • 它可以隐藏 HTML 输出的空格.但是一旦应用程序逻辑尝试发送二进制内容(例如生成的图像)​​,缓冲的无关输出成为一个问题.(需要 ob_clean()作为进一步的解决方法.)

      • 缓冲区大小有限,如果保留默认值,很容易溢出.这也不是罕见的情况,当它发生时.

    因此两种方法都可能变得不可靠 - 特别是在两者之间切换时开发设置和/或生产服务器.这就是为什么输出缓冲是被广泛认为只是一个拐杖/严格来说是一种解决方法.

    另见在手册中,以及更多的利弊:

    但它在另一台服务器上工作!?

    如果您之前没有收到标题警告,那么 来探测是否仍然可以...发送标头.这对有条件地打印很有用信息或应用其他回退逻辑.

    if (headers_sent()) {die("重定向失败.请点击此链接:<a href=...>");}别的{退出(标题(位置:/user.

    有用的后备解决方法是:

    • HTML 标签

      如果您的应用程序在结构上难以修复,那么一个简单的(但有点不专业)允许重定向的方法是注入 HTML 标签.可以通过以下方式实现重定向:

       

      或短暂延迟:

       

      当在 部分之后使用时,这会导致无效的 HTML.大多数浏览器仍然接受它.

    • JavaScript 重定向

      作为替代,JavaScript 重定向可用于页面重定向:

       location.replace(target.html");

      虽然这通常比 <meta> 解决方法更符合 HTML,它导致对支持 JavaScript 的客户端的依赖.

    然而,当真正的 HTTP header() 时,这两种方法都可以接受调用失败.理想情况下,您总是将此与用户友好的消息结合起来,并且可点击链接作为最后的手段.(例如,PECL 扩展可以.)

    为什么setcookie()session_start() 也会受到影响

    setcookie()session_start() 都需要发送一个 Set-Cookie: HTTP 头.因此适用相同的条件,并且将生成类似的错误消息用于过早的输出情况.

    (当然,它们还受到浏览器中禁用的 cookie 的影响甚至代理问题.会话功能显然也依赖于免费磁盘空间和其他

    更多链接

    When running my script, I am getting several errors like this:

    The lines mentioned in the error messages contain header() and calls.

    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.Otherwise the call fails:

    Some functions modifying the HTTP header are:

    • /
    • /
    • /

    Output can be:

    • Unintentional:

    • Intentional:

      • print, echo and other functions producing output
      • Raw <html> sections prior <? code.

    Why does it happen?

    To understand why headers must be sent before output it's necessaryto look at a typical HTTPresponse.

    HTTP/1.1 200 OK
    Powered-By: 

    The page/output always follows the headers.

    When print, echo, <html>) it willflush all collected headers. Afterward it can send all the outputit wants. But sending further HTTP headers is impossible then.

    How can you find out where the premature output occurred?

    The header() warning contains all relevant information tolocate the problem cause:

    Here "line 100" refers to the script where the header() invocation failed.

    The "output started at" note within the parenthesis is more significant.It denominates the source of previous output. In this example, it's auth.and line 52. 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. The application flow must be restructured to avoid that. Use and templating schemes. Ensure header() calls occur before messagesare written out.

      Functions that produce output include


      among others and user-defined functions.

    2. Raw HTML areas

      Unparsed HTML sections in a . file are direct output as well.Script conditions that will trigger a header() call must be notedbefore any raw <html> blocks.

      <!DOCTYPE html>
      <?

      Use a templating scheme to separate processing from output logic.

    3. Whitespace before <? for "script.line 1" warnings

      If the warning refers to output inline 1, then it's mostlyleading whitespace, text or HTML before the opening <? token.

       <?

      Similarly it can occur for appended scripts or script sections:

      ?>
      
      <?

      single linebreak after close tags. But it won'tcompensate multiple newlines or tabs or spaces shifted into such gaps.

    4. UTF-8 BOM

      Linebreaks and spaces alone can be a problem. But there are also "invisible"character sequences that can cause this. Most famously theUTF-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.  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 itspresence. 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 identifyits presence in a file/settings menu (Notepad++ on Windows can identify andremedy 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 to 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 or recode).For tag tidier.It rewrites close and open tags into long and short forms, but also easilyfixes leading and trailing whitespace, Unicode and UTF-x BOM issues:

      It's safe to use on a whole include or project directory.

    5. Whitespace after ?>

      If the error source is mentioned as behind thethen this is where some whitespace or the raw text got written out.The

      It's commonly advised, in particular to newcomers, that trailing ?> eschews a small portion of these cases.(Quite commonly include()d scripts are the culprit.)

    6. Error source mentioned as "Unknown on line 0"

      It's typically a

      • It's occasionally the gzip stream encoding setting.
      • But it could also be any doubly loaded extension= modulegenerating an implicit
    7. Preceding error messages

      If another

      In this case you need to eschew the error,delay the statement execution, or suppress the message with e.g. or -when either doesn't obstruct debugging later on.

    No error message

    If you have error_reporting or display_errors disabled per ,then no warning will show up. But ignoring errors won't make the problem goaway. Headers still can't be sent after premature output.

    So when header("Location: ...") redirects silently fail it's veryadvisable to probe for warnings. Reenable them with two simple commandsatop the invocation script:

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

    Or set_error_handler("var_dump"); if all else fails.

    Speaking of redirect headers, you should often use an idiom likethis for final code paths:

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

    Preferably even a utility function, which prints a user messagein case of header() failures.

    Output buffering as a workaround

    output bufferingis a workaround to alleviate this issue. It often works reliably, but shouldn'tsubstitute for proper application structuring and separating output from controllogic. Its actual purpose is minimizing chunked transfers to the webserver.

    1. The setting nevertheless can help.Configure it in the or even onmodern FPM/FastCGI setups.
      Enabling it will allow

    2. It can likewise be engaged with a call to ob_start();atop the invocation script. Which however is less reliable for multiple reasons:

    Both approaches therefore may become unreliable - in particular when switching betweendevelopment setups and/or production servers. This is why output buffering iswidely considered just a crutch / strictly a workaround.

    See also the 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 to probe ifit's still possible to... send headers. Which is useful to conditionally printinfo or apply other fallback logic.

    if (headers_sent()) {
        die("Redirect failed. Please click on this link: <a href=...>");
    }
    else{
        exit(header("Location: /user.

    Useful fallback workarounds are:

    • HTML <meta> tag

      If your application is structurally hard to fix, then an easy (butsomewhat 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.

    Both approaches however make acceptable fallbacks when genuine HTTP header()calls fail. Ideally you'd always combine this with a user-friendly message andclickable link as last resort. (Which for instance is what the PECL extension does.)

    Why setcookie() and session_start() are also affected

    Both setcookie() and session_start() need to send a Set-Cookie: HTTP header.The same conditions therefore apply, and similar error messages will be generatedfor premature output situations.

    (Of course, they're furthermore affected by disabled cookies in the browseror even proxy issues. The session functionality obviously also depends on freedisk space and other

    Further links

    这篇关于如何修复“标题已发送"