Problem: PHP "Headers Already Sent" Error
The "Headers Already Sent" error in PHP happens when output is sent to the browser before PHP tries to modify headers or start a session. This error can stop scripts from working correctly and cause unexpected behavior in web applications.
Identifying the Source of the Error
Reading the error message
When you see a "Headers Already Sent" error, the error message helps you find the problem. The message usually shows the file name and line number where the error happened. For example:
Warning: Cannot modify header information - headers already sent by (output started at /path/to/file.php:12) in /path/to/file.php on line 23
This message tells you that the headers were sent by line 12 in the file, and the script tried to change headers again on line 23. To fix this, look at the code before line 12 to find any unexpected output.
Tip: Use Output Buffering
To prevent unexpected output, you can use output buffering. Add this at the beginning of your script:
ob_start();
This captures all output and allows you to send headers at any point in your script. Remember to call ob_end_flush()
at the end to send the captured output.
Using error reporting settings to debug
To get more error details, you can change PHP's error reporting settings. Add these lines at the top of your script:
error_reporting(E_ALL);
ini_set('display_errors', 1);
These settings will show all errors and warnings, helping you find issues that might cause early output. Remember to turn off these settings in production for security reasons.
You can also use the headers_sent()
function to check if headers have been sent before trying to change them:
if (!headers_sent()) {
// Safe to send headers
header('Location: example.php');
} else {
// Headers already sent, use another method or show an error
echo "Error: Headers already sent.";
}
This method lets you handle the situation when headers have already been sent, either by using another method or showing an error message to the user.
Common Causes of "Headers Already Sent" Error
Unintentional output before header calls
Some unintentional issues can cause output before header calls:
-
Whitespace before PHP opening tag: Spaces or line breaks before the
<?php
tag can trigger the error. Start your PHP files with the opening tag at the beginning. -
UTF-8 Byte Order Mark (BOM): Some text editors add a BOM at the start of UTF-8 encoded files. This character counts as output. Use a BOM-free UTF-8 encoding when saving PHP files.
-
Previous error messages or notices: If your script generates error messages or notices before sending headers, these will count as output. Use error suppression or proper error handling to prevent this.
Tip: Use Output Buffering
If you can't avoid output before header calls, consider using output buffering. Start your script with ob_start()
to capture all output, and then use ob_end_flush()
after your header calls to send the buffered content:
<?php
ob_start();
// Your PHP code here, including any potential output
header("Location: new-page.php");
ob_end_flush();
?>
Intentional output before header calls
Sometimes, developers output content before sending headers:
-
Echo or print statements: Using
echo
,print
, or similar functions before sending headers will trigger the error. Move all output after your header calls. -
HTML content before PHP code: Any HTML outside of PHP tags that appears before header calls will be sent to the browser immediately. Keep all HTML after your PHP header operations.
To avoid these issues, structure your PHP scripts with all header changes at the top, followed by the main content of your page.
Solutions to Fix "Headers Already Sent" Error
Restructuring code execution order
To fix the "Headers Already Sent" error, change how your code runs:
- Move header() calls to the start of the script: Put all your header() functions at the top of your PHP file, before any output. This includes functions like setcookie() and session_start(). For example:
<?php
header("Content-Type: text/html");
setcookie("user", "John", time() + 3600);
session_start();
// Rest of your code here
?>
- Organize code to prevent early output: Group all your processing logic before any output. Use variables to store data you want to display later. Here's a basic structure:
<?php
// 1. Initialize variables
// 2. Process form data
// 3. Database operations
// 4. Set headers and cookies
// 5. HTML output
?>
Tip: Use include files for better organization
Split your PHP code into separate files for different functions. Use include() or require() to add these files at the top of your main script, before any output. This helps keep header-related code separate from output-generating code.
Removing unintended output
-
Remove whitespace and BOM: Check your PHP files for extra spaces or line breaks before the opening
-
Address error messages and notices: Fix any PHP errors or warnings that appear before your header calls. Use error suppression or proper error handling. For example:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 0);
// Your code here
?>
Using output buffering
- Implement ob_start() function: Output buffering can help when you can't avoid early output. Add this at the start of your script:
<?php
ob_start();
// Your code here
ob_end_flush();
?>
- Configure output_buffering in php.ini: For a server-wide solution, you can enable output buffering in your php.ini file:
output_buffering = On
This setting captures all output automatically, allowing you to send headers at any point in your script.
While output buffering can solve the "Headers Already Sent" error, it's better to structure your code correctly to avoid the issue in the first place.