No Fallthrough
ID |
php.no_fallthrough |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Php |
Tags |
reliability, switch |
Description
Reports a non-empty switch case whose statement list does not end in a control-flow
terminator (break, return, throw, continue, goto, or exit/die) and that is
followed by another case or the default clause. Execution then falls through into the
next case, which is almost always unintended.
Rationale
Unlike many languages, PHP switch cases do not stop at the end of their body: once a
matching case runs to its last statement, control continues into the following case unless
a terminator is reached. A missing break therefore executes code meant for a different
case, producing subtle, hard-to-find bugs. Intentional grouping with empty cases
(case A: case B:) is fine and is not reported, and the final block is never flagged
because there is nothing after it to fall into.
<?php
switch ($code) {
case 1:
$a = doOne(); // FLAW — no break, falls into case 2
case 2:
return doTwo(); // OK — ends in return
case 3:
case 4: // OK — empty grouped case, deliberate fall-through
handle();
break; // OK — ends in break
default:
reset();
break;
}
Remediation
Add an explicit terminator (break, return, throw, …) as the last statement of every
non-empty case. If the fall-through is intentional, leave the case body empty so it groups
with the next case, or restructure the logic to make the shared handling explicit.