How to Prevent Headers Already Sent Error in PHP
The “headers already sent” error is a common issue PHP developers
face, occurring when code attempts to send HTTP headers after output has
already been sent to the browser. This article explains how the native
headers_sent() function prevents this fatal error by
checking the output status of your script, allowing you to safely manage
redirects and cookie creation.
Understanding the Error
In the HTTP protocol, response headers must always precede the actual
response body (HTML, JSON, plain text, etc.). In PHP, functions like
header(), setcookie(), and
session_start() modify the response headers. If your script
outputs even a single character of HTML, a blank space, or a Byte Order
Mark (BOM) before these functions are called, PHP automatically sends
the headers and blocks any future attempts to modify them, resulting in
a fatal error or warning.
How headers_sent() Prevents the Error
The headers_sent() function checks if the HTTP headers
have already been dispatched to the client. It returns true
if headers have been sent, and false otherwise.
By placing this function inside a conditional statement, you can ensure that your script only attempts to send headers when it is safe to do so.
if (!headers_sent()) {
header('Location: https://example.com/dashboard');
exit;
} else {
// Fallback method if headers are already sent
echo '<script>window.location.href="https://example.com/dashboard";</script>';
echo '<noscript><meta http-equiv="refresh" content="0;url=https://example.com/dashboard"></noscript>';
exit;
}In this example, if output has already started, the script bypasses
the standard PHP header() redirect (which would throw a
fatal error) and gracefully falls back to a JavaScript or HTML-based
redirect.
Debugging with headers_sent()
Beyond prevention, headers_sent() can also help you
locate the exact source of premature output. The function accepts two
optional pass-by-reference variables: $file and
$line.
if (headers_sent($file, $line)) {
echo "Headers were already sent in {$file} on line {$line}.";
}When headers have already been sent, PHP populates these variables
with the filename and the exact line number where the output started.
This makes it easy to track down accidental whitespaces,
echo statements, or file inclusions that triggered the
early send.