Reducing Cyclomatic Complexity Techniques
debt(d3/e3/b3/t5)
Closest to 'default linter catches the common case' (d3). The term's detection_hints list phpmd, phpcs, eslint, and sonarqube — these are standard quality tools that flag high cyclomatic complexity by default. Most teams with any CI pipeline will catch CC > 10 functions automatically.
Closest to 'simple parameterised fix' (e3). The quick_fix describes adding early returns, extracting boolean expressions to named functions, and decomposing large functions — these are localized refactors within a single component, not architectural changes. Each technique is a well-understood pattern that can be applied incrementally.
Closest to 'localised tax' (b3). Cyclomatic complexity awareness applies across all contexts (web/cli/queue-worker), but the burden of maintaining low-CC code is mostly confined to individual functions and modules. It doesn't define system architecture or create cross-cutting dependencies — it's a local quality property that each function pays individually.
Closest to 'notable trap' (t5). The misconception field explicitly states 'Low cyclomatic complexity always means simple code' — developers often assume CC is a complete measure of complexity, but nested callbacks, complex boolean expressions (mentioned in common_mistakes), and other structural complexity can hide behind low CC numbers. This is a documented gotcha that experienced developers eventually learn.
TL;DR
Explanation
Cyclomatic complexity (CC) = branches + 1. CC > 10 is complex, > 20 is very complex and untestable. Techniques to reduce: (1) Early returns / guard clauses eliminate nesting, (2) Extract complex conditions to named predicate functions, (3) Replace switch/if chains with lookup tables or strategy pattern, (4) Decompose large functions into smaller ones, (5) Use polymorphism instead of type-checking conditions, (6) Replace nested ternaries with match/switch or named functions. Tools: PHPStan, PHP_CodeSniffer (PHPMD), ESLint (complexity rule), SonarQube.
Common Misconception
Why It Matters
Common Mistakes
- Ignoring CC metrics in code review.
- Reducing CC by moving complexity into long boolean expressions.
- Not using early returns — unnecessary else after return increases nesting.
Code Examples
function process($user, $action) {
if ($user) {
if ($user->isActive()) {
if ($action === 'delete') {
if ($user->isAdmin()) {
// do delete
} else {
throw new Exception('No permission');
}
}
} else {
throw new Exception('Inactive');
}
} else {
throw new Exception('No user');
}
}
function process($user, $action) {
if (!$user) throw new Exception('No user');
if (!$user->isActive()) throw new Exception('Inactive');
if ($action === 'delete') deleteUser($user);
}
function deleteUser($user) {
if (!$user->isAdmin()) throw new Exception('No permission');
// do delete
}