Pure Function
debt(d7/e3/b3/t5)
Closest to 'only careful code review or runtime testing' (d7). PHPStan/Psalm don't flag impurity by default; spotting global reads, static state, or DB calls hidden in calculator-shaped functions requires human review.
Closest to 'simple parameterised fix' (e3). Per quick_fix, extracting a pure function means passing inputs as arguments instead of reading globals — a small refactor within the function, occasionally rippling to a few callers.
Closest to 'localised tax' (b3). Purity is a per-function discipline applied across web/cli/queue contexts, but each impure function imposes only localised testing/caching friction rather than shaping the whole system.
Closest to 'notable trap' (t5). The misconception (that purity doesn't apply to PHP) plus the caching-impure-results mistake is a documented gotcha most devs eventually learn, but the 'obvious' approach isn't always wrong.
Also Known As
TL;DR
Explanation
A pure function has two properties: referential transparency (same inputs always produce the same output) and no side effects (it doesn't modify external state, perform I/O, or depend on mutable global state). Pure functions are the easiest code to test (no mocking required), reason about, and safely parallelise. In PHP, extracting business logic into pure static functions or methods that accept all dependencies as parameters maximises testability even without a functional programming framework.
Common Misconception
Why It Matters
Common Mistakes
- Functions that read global state, static properties, or the database — impure despite looking like calculators.
- Functions that modify their arguments — callers do not expect mutation from a getter-style function.
- Not distinguishing pure utility functions from impure service methods — architecture clarity suffers.
- Caching impure function results — stale cache returns wrong values when underlying state changes.
Code Examples
// Impure: depends on external state, has a side effect
function applyDiscount(float $price): float {
$rate = Config::get('discount_rate'); // hidden dependency
Log::info('Discount applied'); // side effect
return $price * (1 - $rate);
}
// Pure: output determined solely by inputs, no side effects
function applyDiscount(float $price, float $rate): float {
return $price * (1 - $rate);
}
// Caller injects the rate; logging done at call site if needed