Dead Condition
debt(d3/e1/b1/t5)
Closest to 'default linter catches the common case' (d3). PHPStan, Psalm, and Rector (all listed in detection_hints.tools) catch dead conditions automatically at moderate levels. PHPStan flags these at level 6+, making detection fairly routine with standard static analysis tooling in PHP projects.
Closest to 'one-line patch or single-call swap' (e1). The quick_fix explicitly states 'Remove conditions that are always true or false' — this is typically a single-line deletion or simplification of the conditional expression, requiring no architectural changes.
Closest to 'minimal commitment' (b1). A dead condition is a localized bug in a single conditional statement. It doesn't impose any structural weight on the codebase — once fixed, there's no ongoing maintenance cost or gravitational pull on future development.
Closest to 'notable trap' (t5). The misconception field reveals the trap: developers assume dead conditions are 'harmless since they don't affect runtime' but they actually 'indicate a logic error somewhere.' The why_it_matters section shows the serious case — a dead condition like 'if ($isAdmin || true)' silently disables security checks. This is a documented gotcha that experienced devs learn, but the 'obvious' assumption that unreachable code is merely wasteful rather than symptomatic of a bug is a meaningful cognitive trap.
Also Known As
TL;DR
Explanation
Dead conditions waste cognitive overhead — readers reason about a branch that can never change the outcome. They typically arise from: contradictory conditions (if $x > 5 && $x < 3), type coercion surprises, copy-paste errors, or refactoring that left conditions stale. Static analysers (PHPStan level 6+, Psalm) detect many dead conditions automatically. The fix is to remove the dead branch and document why the condition was wrong.
Common Misconception
Why It Matters
Common Mistakes
- Checking a value against a range it can never satisfy: if ($percent > 100 && $percent < 0).
- Checking a typed parameter for a condition its type makes impossible: if (is_string($str) && !is_string($str)).
- Post-loop conditions that are always true after the loop has terminated.
- Copy-paste conditions: checking the same variable twice with the same comparator.
Code Examples
// Dead conditions — always true or always false:
function isValidPercent(int $p): bool {
// int cannot be both > 100 AND < 0 simultaneously:
if ($p > 100 && $p < 0) { // Always false — dead branch
return false;
}
return true; // Always reached
}
// Always true — $items is always an array here:
$items = getItems(); // returns array
if (is_array($items) || count($items) > 0) { /* always executes */ }
// Corrected conditions — actually reachable:
function isValidPercent(int $p): bool {
if ($p < 0 || $p > 100) { // OR not AND — correct range check
return false;
}
return true;
}
// Simplified — remove dead branch:
$items = getItems();
if (count($items) > 0) { /* meaningful check */ }