Boolean Parameters (Flag Arguments Smell)
debt(d6/e3/b3/t5)
Closest to 'specialist tool catches it' (d5), +1. While phpstan and phpcs are listed as detection tools, the detection_hints explicitly say automated: no. These tools can flag boolean parameters in some cases (e.g. custom phpcs sniffs), but reliably detecting when a boolean flag is a genuine smell vs. acceptable usage requires code review judgment. Falls between specialist tooling and careful code review.
Closest to 'simple parameterised fix' (e3). The quick_fix says to replace a boolean flag parameter with two distinct methods or an enum. This is a straightforward refactor — rename/split the method and update call sites — but it typically touches more than one line since callers must be updated too. Still localised to one method and its callers, so e3 fits.
Closest to 'localised tax' (b3). Boolean parameters are a per-method/per-API concern. They make individual call sites harder to read and the method harder to extend, but they don't impose a system-wide architectural constraint. The smell is localised — each instance can be fixed independently without cross-cutting impact. Applies across web/cli/queue contexts but each instance is self-contained.
Closest to 'notable trap' (t5). The misconception states that 'a boolean parameter is always cleaner than two separate methods' — this is a well-documented gotcha that most developers eventually learn but initially get wrong. Many competent developers coming from other paradigms default to boolean flags thinking they reduce code duplication, not realizing they sacrifice readability at call sites. The tri-state evolution pitfall (bool becoming null/false/true) adds another documented surprise.
Also Known As
TL;DR
Explanation
Martin Fowler calls boolean parameters (flag arguments) a smell because they advertise that the function does two different things. A call like sendEmail($user, true) tells the reader nothing; sendEmail($user, $sendCopy=true) is marginally better but still bifurcates the function. The remedy is to split into two clearly-named functions: sendEmail($user) and sendEmailWithCopy($user), or use an enum/value object to express the mode explicitly. Named arguments (PHP 8.0) mitigate the readability problem but don't fix the underlying design issue.
Common Misconception
Why It Matters
Common Mistakes
- Multiple boolean parameters: render($template, true, false, true) — impossible to read at call site.
- Using a boolean to switch between two fundamentally different behaviours — create two methods instead.
- Not using named arguments (PHP 8) to document boolean flags at call sites.
- Booleans that change over time to tri-state (null/false/true) — use an enum instead.
Code Examples
function createUser(string $name, bool $isAdmin): User { ... }
function createUser(string $name): User { ... }
function createAdminUser(string $name): User { ... }