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?
P粉0716024062023-10-10 11:29:08
Send any content before sending HTTP headers (using setcookie
or header
). 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 BOM EF 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 the display_errors
or error_reporting configuration and you should resolve the issue. $_POST['input']
without using empty
or isset
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. with ob_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.
P粉0879514422023-10-10 09:54:05
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:
The output can be:
Unintentional:
or after
?>deliberately:
print
, echo
and other functions that produce output The original
section before the code.
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:
HTTP/1.1 200 OK Powered-By: PHP/5.3.7 Vary: Accept-Encoding Content-Type: text/html; charset=utf-8PHP page output page Content
Some more output follows...
and
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.
header()
The warning contains all relevant information
Cause of positioning problem:
Here "Line 100" refers to 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 line 52
. This is where you have to look for premature output.
Typical reasons:
print
and echo
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 the header()
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.
.php file is also output directly.
One must pay attention to the script conditions that will trigger the header()
call
Before any original blocks.
Use a template scheme to separate processing from output logic.
The space before it means "script.php line 1" warning
If the warning refers to the inline output 1
, then mainly
Starting Leading space before tag, text, or HTML.
Similarly this can happen with additional scripts or script sections:
?>PHP actually takes up a single newline after the closing tag. but it won't Compensates for multiple newlines, tabs, or spaces moved into such gaps.
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.
There are also automated tools to check and rewrite text files
(sed
/awk代码>
or recode
).
For PHP, specifically the phptags
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:
phptags --whitespace *.php
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 for include()d
scripts to be the culprit.)
If there is no error source, it is usually a PHP extension or php.ini setting Concrete.
gzip
Stream encoding settings
or ob_gzhandler
. extension=
module
Generate implicit PHP startup/warning messages. 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.
If you have disabled error_reporting
or display_errors
according to php.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:
error_reporting(E_ALL); ini_set("display_errors", 1);
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:
exit(header("Location: /finished.html"));
It is best to be a practical function that prints user messages
If header()
fails.
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:
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.
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.
if (headers_sent()) { die("Redirect failed. Please click on this link: "); } else{ exit(header("Location: /user.php")); }
Useful fallback solutions are:
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.
As an alternative, JavaScript redirection Can be used for page redirection:
sssccc
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. )
setcookie()
and session_start()
are also affectedsetcookie()
and session_start()
both require sending the Set-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.)