When running my script, I receive several errors like the following:
Warning: Unable to modify header information - header already sent by /some/file.php (Output starts at /some/file.php:12) < Line 23<第23行
The line mentioned in the error message contains the header()
and setcookie()
calls.
What could be the reason for this? How to solve it?
Send any content before sending HTTP headers (using
setcookie
orheader
). Common reasons for outputting something before HTTP headers are:Unexpected spaces, usually at the beginning or end of the file, as shown below:
To avoid this, just omit the trailing
?>
- it's not needed anyway.3F 3C
. You can safely remove BOMEF BB BF
from the beginning of the file.echo
,printf
,readfile
,passthru
,>
waitdisplay_errors
php.ini property is set. Instead of crashing due to programmer error, php silently fixes the error and issues a warning. Although you can modify thedisplay_errors
or error_reporting configuration and you should resolve the issue.A common cause is accessing undefined elements in the array (e.g.
$_POST['input']
without usingempty
orisset
to test whether the input is set), or use an undefined constant instead of a string literal (as in$_POST[input]
, note the missing quotes).Turning on Output Buffering should do the trick; all output after calling
ob_start
is buffered in memory until you release the buffer, e.g. withob_end_flush
.However, while output buffering can avoid these problems, you should really determine why your application is outputting the HTTP body before the HTTP headers. It's like answering the phone and discussing your day and the weather, then telling the caller that he dialed the wrong number.
No output before sending header!
The functions that send/modify HTTP headers must be called before any output can be made. Summary⇊ Otherwise the call fails:
Some functions that modify HTTP headers are:
Header
/header_remove
session_start
/session_regenerate_id
setcookie
/setrawcookie
The output can be:
Unintentional:
Space- before
- SpecificUTF-8 Byte Order Mark
- Previous error message or notification
or after
?>deliberately:
print
,echo
and other functions that produce outputThe original
section before the code.
Why does this happen?
This is necessary to understand why headers must be sent before outputting View typical HTTP reply. The PHP script mainly generates HTML content and also passes a Set of HTTP/CGI headers sent to the web server:
Page/Output always follows the title. PHP must pass First the header is sent to the web server. It can only do this once. They can no longer be modified after double wrapping.
When PHP receives the first output (
print
,echo
,), it will RefreshAll collected headers. After that it can send all output It wants to. But sending further HTTP headers is not possible.
How to find out where premature output occurs?
header()
The warning contains all relevant information Cause of positioning problem:Here "Line 100" refers to
The "header()
The script that failed to call .output starts with " comment inside brackets is more important. It represents the source of previous output. In this example it is
auth.php
and line52
. This is where you have to look for premature output.Typical reasons:
Print, echo
Intentional output ofprint
andecho
statements will terminate the opportunity to send HTTP headers. The application process must be restructured to avoid this situation. Using Function and template solutions. Make sure theheader()
call occurs before the message It's all written down.Functions that generate output include
print
、echo
、printf
、vprintf
trigger_error
,ob_flush
,ob_end_flush
,var_dump
,print_r
readfile
、passthru
、flush
、imagepng
、imagejpeg
And other and user-defined functions.
Original HTML area
The unparsed HTML part in the.php file is also output directly. One must pay attention to the script conditions that will trigger the
header()
call Before any originalblocks.
The space before it means "script.php line 1" warning
If the warning refers to the inline output
1
, then mainly StartingLeading space before tag, text, or HTML.
UTF-8 BOM
Newlines and spaces alone can be a problem. But there are also “invisible” Character sequences that may cause this. The most famous is UTF-8 BOM (Byte Order Mark) Most text editors don't display it. It is the byte sequence
EF BB BF
, which is optional and redundant for UTF-8 encoded documents. However PHP must treat it as raw output. It may appear in the output as the characters
(if the client interprets the document as Latin-1) or similar "garbage".Especially graphical editors and Java-based IDEs don't notice it Be present. They don't visualize it (as required by the Unicode standard). However, most programmers and console editors do:
This makes it easy to detect problems as early as possible. Other editors may recognize It is present in the File/Settings menu (Notepad on Windows recognizes and Solve the problem), Another option to check the existence of the BOM is to use a hex editor. On *nix systems
hexdump
is usually available, If not a graphical variant that simplifies reviewing these and other questions:A simple workaround is to set your text editor to save files as "UTF-8 (no BOM)" Or similar nomenclature. Often newbies will resort to creating new files and then copying and pasting the previous code back.
Correction Utility
There are also automated tools to check and rewrite text files (
sed
/awk代码>
orrecode
). For PHP, specifically thephptags
tag tidier. It rewrites closing and opening tags into long and short forms and is easy too Fixed leading and trailing whitespace, Unicode and UTF-x BOM issues:It is safe to use on the entire include or project directory.
? >
If the error source is mentioned later Close
?>
Well this is where some blank or raw text is written. The PHP closing tag does not terminate script execution at this time. Any text/space characters after it will be written out as page content still.It is generally recommended, especially for newbies, to follow
?>
PHP The closing tag should be omitted. This avoids a small number of these cases. (It's common forinclude()d
scripts to be the culprit.)The source of the error is called "Unknown line 0"
If there is no error source, it is usually a PHP extension or php.ini setting Concrete.
gzip
Stream encoding settings orob_gzhandler
.extension=
module Generate implicit PHP startup/warning messages.Previous error message
If another PHP statement or expression causes a warning message or Note is printed, which also counts as premature output.
In this case you need to avoid errors, Delay statement execution, or suppress messages using e.g.
isset()
or@()
- When either doesn't hinder debugging later.No error message
If you have disabled
error_reporting
ordisplay_errors
according tophp.ini
, Then no warning will appear. But ignoring the error doesn't solve the problem leave. Still unable to send headers after premature output.So it's very serious when
header("Location: ...")
the redirect fails silently Probe warning is recommended. Re-enable them with two simple commands On top of the calling script:Or
set_error_handler("var_dump");
If all other methods fail.Speaking of redirect headers, you should always use an idiom like this This is the final code path:
It is best to be a practical function that prints user messages If
header()
fails.Output buffering as a workaround
PHP Output Buffering is a workaround to alleviate this problem. It usually works reliably, but it shouldn't Override correct application structure and separate output from control logic. Its actual purpose is to minimize chunked transfers to the web server.
output_buffering=
Still, the settings help. Configure it in php.ini or via .htaccess Even .user.ini Modern FPM/FastCGI setup.Enabling this will allow PHP to buffer output instead of passing it to the web server immediately. PHP can therefore aggregate HTTP headers.
It can also be done by calling
ob_start();
on top of the calling script. However, it is less reliable for a number of reasons:Even if
starts the first script, a space or The BOM may be scrambled and invalid before rendering.
It can hide the whitespace of HTML output. However, once the application logic attempts to send binary content (such as a generated image), Buffered extraneous output becomes a problem. (requires ob_clean()) as a further workaround. )
The buffer size is limited and can easily overflow if left at the default value. This situation is not uncommon and is difficult to track一个> when it happens.
Therefore, both methods can become unreliable - especially when switching between the two Development setup and/or production server. This is why output buffering is Widely considered to be just a crutch/strictly a workaround.
See alsoBasic usage examples In the manual, and more pros and cons:
But it works on other servers! ?
If you did not receive a header warning before, output buffering php.ini settings already changed. It may not be configured on the current/new server.
Use
headers_sent() to check
You can always use
headers_sent()
to detect whether It's still possible... to send headers. This is useful for conditional printing information or apply other fallback logic.Useful fallback solutions are:
HTML
Tags
If your application is structurally difficult to fix, then a simple (but A bit unprofessional) The way to allow redirection is to inject HTML
Label. Redirection can be achieved in the following ways:
Or short delay:
This results in invalid HTML when using more than
sections. Most browsers still accept it.
JavaScript Redirect
As an alternative, JavaScript redirection Can be used for page redirection:
While this is generally more HTML-compliant than the
solution, It results in a dependency on JavaScript-enabled clients.
However, both methods produce acceptable fallbacks when the real HTTP header() The call failed. Ideally, you always combine this with a user-friendly message, Clickable links as a last resort. (For example, http_redirect() The PECL extension does. )
Why
setcookie()
andsession_start()
are also affectedsetcookie()
andsession_start()
both require sending theSet-Cookie:
HTTP header. Therefore, the same conditions apply and a similar error message will be generated Used in the case of premature output.(Of course, they are also affected by disabling cookies in your browser Even agency issues. The session feature obviously also relies on free Disk space and other php.ini settings, etc.)
More links