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.