I get "Warning: Cannot modify header information - headers already sent by (output started at /var/www/login.php:3)" when I call header('Location: dashboard.php') or session_start(). Why?
DEV3 Developer Forum
How do I fix 'Cannot modify header information - headers already sent' in PHP?
Every post is reviewed first. Usually reviewed within 24 hours.
1 reply
HTTP headers (including redirects and the session cookie) must be sent before any body output. Once PHP outputs even one byte, headers are sent and later header(), setcookie() or session_start() calls fail. The warning tells you where output started: login.php:3.
Typical causes
- Whitespace or HTML before
<?php, including a blank line at the top of the file or an included file. - Closing
?>tag followed by newline at the end of an include file. Omit the closing tag in pure PHP files, which is the PSR standard. - UTF-8 BOM added by some editors at the beginning of the file. Save as "UTF-8 without BOM". Check with
head -c 3 file.php | xxd. echo,print_rorvar_dumpdebugging before the redirect.- Warnings or notices printed to the page before the header (the error message itself is output).
- Included files such as
config.phporfunctions.phpthat output text.
Fix pattern
<?php
declare(strict_types=1);
session_start();
// logic first, no output
if (!isset($_SESSION['user_id'])) {
header('Location: /login.php');
exit; // always stop after a redirect
}
// HTML below
?>
<!doctype html>
Note exit after header('Location: ...'): PHP keeps running the script otherwise.
Workaround: output buffering
ob_start(); // at the very top
// ... later
ob_end_flush();
or output_buffering = 4096 in php.ini. It hides the problem rather than fixing it, so use it only as a safety net.
Debug: headers_sent($file, $line) returns the file and line where output started:
if (headers_sent($file, $line)) {
exit("Output started in $file:$line");
}
Also never send a redirect with a relative path on unusual setups; use an absolute path such as /dashboard.php.