Refactoring Boolean Flag Parameters
debt(d5/e5/b5/t5)
Closest to 'specialist tool catches it' (d5). The detection_hints list phpmd and phpstan, both specialist static analysis tools that require configuration and intentional use. The code_pattern `bool $|boolean $` is detectable but not caught by default linters in typical setups — it requires running these tools deliberately.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix mentions replacing boolean params with enums or separate functions, extracting options into value objects for 3+ flags — these changes ripple through all call sites of the affected function, touching multiple files and requiring coordinated updates across callers and the function definition itself.
Closest to 'persistent productivity tax' (b5). The term applies_to web, cli, and queue-worker contexts — broad reach. Boolean flags in APIs impose ongoing cognitive load on every developer reading or extending those functions, slowing down work streams that touch those APIs. However, it's not quite architectural (b7) since it's function-level rather than system-shaping.
Closest to 'notable trap' (t5). The misconception is explicit: developers believe PHP 8 named arguments fix the underlying design problem, but they only improve call-site readability — the boolean flag design issue persists. This is a documented gotcha that many developers learn, matching the t5 anchor of a notable documented trap most devs eventually encounter.
TL;DR
Explanation
function createUser($name, true, false, true) — what do those booleans mean? Boolean parameters (flag arguments) make call sites unreadable. Refactoring options: (1) Replace with enums/named constants, (2) Split into separate functions (createAdminUser, createGuestUser), (3) Use options object/named arguments, (4) Builder pattern for complex construction. PHP 8.0 named arguments partially solve the readability issue at call sites but don't fix the function signature. Martin Fowler's 'Remove Flag Argument' refactoring addresses this systematically.
Common Misconception
Why It Matters
Common Mistakes
- Adding boolean params to extend existing functions instead of adding new ones.
- Using boolean to toggle completely different behaviour — should be separate functions.
- Not using named arguments (PHP 8) at minimum to document existing boolean params.
Code Examples
createUser('Paul', true, false, true); // What are these booleans?
function createUser(string $name, bool $isAdmin, bool $sendEmail, bool $active) {}
// Option 1: Named enum
enum UserRole { case Admin; case Guest; }
createUser('Paul', UserRole::Admin);
// Option 2: Separate functions
createAdminUser('Paul');
createGuestUser('Paul');
// Option 3: Options object
createUser('Paul', new UserOptions(role: UserRole::Admin, active: true));