Headers Already Sent Error
debt(d3/e3/b3/t5)
Closest to 'default linter catches the common case' (d3). The term's detection_hints list phpcs and php-cs-fixer as tools that can catch obvious cases like echo before header(). However, some causes (BOM characters, whitespace in included files) require more careful scanning, pushing slightly above d3 but not reaching specialist tool territory.
Closest to 'simple parameterised fix' (e3). The quick_fix suggests adding ob_start() at bootstrap and auditing included files for whitespace/BOM. This is more than a one-line patch but remains a localized fix pattern—adding output buffering and cleaning up file headers doesn't require cross-cutting refactors.
Closest to 'localised tax' (b3). This applies only to web contexts per applies_to, not CLI or queue workers. Once ob_start() is in place or files are cleaned, the issue doesn't impose ongoing maintenance burden. It's not a load-bearing architectural choice but a one-time cleanup with a simple preventive measure.
Closest to 'notable trap' (t5). The misconception field explicitly states developers wrongly believe 'only echo and print cause this' when whitespace outside PHP tags, BOM characters, and var_dump() also trigger it. This is a documented gotcha that most PHP developers eventually learn through painful debugging, but it contradicts the intuitive expectation that only explicit output matters.
Also Known As
TL;DR
Explanation
HTTP headers must be sent before any response body. The moment PHP outputs any character — a space before the opening PHP tag, a BOM in a UTF-8 file, or an echo statement — headers are flushed and cannot be modified. Common culprits: whitespace before the opening PHP tag, echo or print before a redirect, BOM in included files. Output buffering (ob_start()) delays output so headers can still be set.
Common Misconception
Why It Matters
Common Mistakes
- Whitespace or BOM before the opening PHP tag in included files
- echo or var_dump() debugging statements left before session_start()
- Not using ob_start() as a safety net in legacy applications
Code Examples
<?php
echo 'Hello'; // Output sent
header('Location: /login'); // Warning: Cannot modify header information — headers already sent
<?php
// No output before headers:
if (!$authenticated) {
header('Location: /login');
exit;
}
echo 'Hello authenticated user';