Division by Zero & DivisionByZeroError
debt(d5/e3/b3/t9)
Closest to 'specialist tool catches it' (d5). The detection_hints list phpstan and psalm as the tools that catch this pattern (code_pattern: '/ $|intdiv\(|% $'). These are specialist static analysis tools, not default linters or compiler errors, so d5 is the right anchor.
Closest to 'simple parameterised fix' (e3). The quick_fix prescribes a guard check (if ($divisor !== 0)) or swapping to fdiv()/intdiv() with try/catch — a small, localised code change at each division site. It doesn't require cross-file refactoring, so e3 fits; slightly better than e5.
Closest to 'localised tax' (b3). The concept applies broadly (web, cli, queue-worker) but each instance is a localised arithmetic guard. It doesn't impose a persistent structural tax on all future maintainers or shape the architecture; affected sites are isolated. b3 is appropriate.
Closest to 'catastrophic trap — the obvious way is always wrong' (t9). The misconception field states explicitly: developers expect '$a / 0' to throw DivisionByZeroError — it doesn't. It silently returns false (PHP 7) or INF (PHP 8). The behaviour directly contradicts the named exception and the intuition from every other language, and the result propagates silently through calculations. This is a t9 canonical trap.
TL;DR
Explanation
PHP has two division behaviours: intdiv($a, 0) and $a % 0 throw DivisionByZeroError. However $a / 0 returns false (with E_WARNING) in PHP 7 and INF/NAN in PHP 8 — it never throws. fdiv($a, 0) always returns INF/NAN per IEEE 754 with no warning. Always guard divisions with a zero check or use fdiv() when IEEE behaviour is acceptable.
Common Misconception
Why It Matters
Common Mistakes
- Not checking divisor before dividing.
- Relying on the exception from / — it won't throw.
- Not handling INF/NAN in float calculations.
Code Examples
$rate = $total / $count; // If $count = 0: false or INF
$rate = $count > 0 ? $total / $count : 0.0;
// Or use fdiv for IEEE-compliant behaviour
$rate = fdiv($total, $count); // Returns INF if $count=0, no warning
// intdiv must be guarded
try {
$result = intdiv($total, $count);
} catch (DivisionByZeroError $e) {
$result = 0;
}